算法第一次作业
主要写一下自己写代码时所遇到的坑点,代码基本都是与网上的类似。
Problem A. 优美的立方质数
时间限制 1000 ms
内存限制 64 MB
题目描述
如果一个质数能被表示为三个不同的质数的和的形式,那么我们称它为立方质数。现在给你一个数n,判断它是不是立方质数。
输入数据
正整数n,n<=1000
输出数据
Yes或者No
样例输入
19
样例输出
Yes
代码:这个代码主要的难点就是判断的哪一行,很容易缺少条件
`
//#include <bits/stdc++.h>
include<stdio.h>
include
include <math.h>
using namespace std;
bool iszhishu(int n) {
if (n == 1)return false;
else if (n == 2 || n == 3)return true;
for (int i = 2; i <= sqrt(n); i ++) {
if (n % i == 0)return false;
}
return true;
}
int main()
{
int x,flag = 0;
cin >> x;
if (!iszhishu(x)) {
cout << "No" << endl;
return 0;
}
else {
for (int i = 1; i < x; i++) {
if (iszhishu(i)) {
for (int j = i + 1; j < x; j++) {
if (iszhishu(j) && iszhishu(x - i - j) && (x - i - j) != i && (x - i - j) != j&& (x - i - j)>1) {
//cout << i << " " << j << endl;
flag = 1;
}
}
}
}
}
if (flag == 1)cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
`
Problem B. 课堂作业-6-2
时间限制 1000 ms
内存限制 64 MB
题目描述
我们有n根的木棍。现在从这些木棍中切割出来m条长度相同的木棍,问这m根木棍最长有多长?
输入数据
第一行输入两个数字,n(1<=n<=1000)为木棍数目,m(1<=m<=1000)为需要切割出的相同长度的木棍数目 随后n个正整数,表示原始木棍的长度(<=10000)
输出数据
每组输出一行结果,表示切割后绳子的最长长度(保留两位小数)
样例输入
4 5
5 6 7 8
样例输出
4.00
这个的主要难点就是刚开始接触,忘记了二分法,基本上没有坑点。
`#include
include
include
using namespace std;
double jisuan(int n, int m, vector
int totallen = 0;
for (int i = 0; i < n; i++) {
totallen += len[i];
}
double l = 0.0, r = 0.0;
r = totallen*1.0 / m;
while (r -l >1e-6) {
double mid = l + (r - l) / 2;
int count = 0;
for(int i = 0; i < n; i++) {
count += len[i] / mid;
}
if (count >= m) {
l = mid;
}
else {
r = mid;
}
}
return r;
}
int main()
{
int n, m;
cin >> n >> m;
vector
for (int i = 0; i < n; i++) {
cin >> len[i];
}
double lenx = jisuan(n, m, len);
printf("%.2f\n", lenx);
}f`
Problem C. 李老师的幸运数字
时间限制 1000 ms
内存限制 64 MB
题目描述
李老师的lucky number 是3,5和7,他爱屋及乌,还把所有质因数只有3,5,7的数字认定为lucky number,比如9, 15, 21, 25等等。请聪明的你帮忙算一算小于等于x的lucky number有多少个?
输入数据
一个正整数x,3=<x<=1000000000000
输出数据
小于等于x的lucky number的个数。
样例输入
49
样例输出
11
样例说明
int存不下
`#include
include
include
using namespace std;
int main()
{
vector
long long x;
cin >> x;
int a = 0, b = 0, c = 0;
while (1)
{
long long n3 = v[a] * 3;
long long n5 = v[b] * 5;
long long n7 = v[c] * 7;
long long Min = min(min(n3, n5), n7);
if (Min == n3)
a++;
if (Min == n5)
b++;
if (Min == n7)
c++;
if (Min > x)
break;
if (Min != v.back())
v.push_back(Min);
}
cout << v.size() - 1 << endl;
return 0;
}`
这个使用双层循环是超时的,暂时只找到这一种方法。
Problem D. 思维之花-简单背包
时间限制 1000 ms
内存限制 64 MB
题目描述
李老师正准备暑假旅行,他有一个容量为L的行李箱和n个物品(n不超过20),每个物品都有自己的体积,物品可以放入行李箱,但行李箱中物品的总体积不能超过行李箱容量,李老师现在想知道他有多少种携带物品的方案(一个物品都不带也算一种方案)
输入数据
第一行为两个正整数n和L,分别代表物品总数和行李箱容量,n<=20,L<=1e9 接下来一行为n个正整数vi,代表第i个物品的体积,vi<=1e8
输出数据
方案数
样例输入
3 10
2 4 5
样例输出
7
也是基础题,主要是dfs,需要多加练习
`#include
include
include
typedef long long ll;
using namespace std;
int n, l;
int a[20] = { 0 };
int cnt = 0;
void dfs(int x, int tot) {
if (tot >= l)return;
cnt++;
for (int i = x + 1; i < n && tot + a[i]<l; i++) {
dfs(i, tot + a[i]);
}
return;
}
int main()
{
cin >> n >> l;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);
dfs(-1, 0);
cout << cnt << endl;
}`一边没过的原因是提交的时候,忘了把调试代码去掉了。
Problem E. 课堂作业-7-2
时间限制 1000 ms
内存限制 64 MB
题目描述
有一条河,河中间有一些石头,已知石头的数量和相邻两块石头之间的距离。现在可以移除一些石头,问最多移除m块石头后(首尾两块石头不可以移除),相邻两块石头之间的距离的最小值最大是多少。
输入数据
第一行输入两个数字,n(2<=n<=1000)为石头的个数,m(0<=m<=n-2)为可移除的石头数目 随后n-1个数字,表示顺序和相邻两块石头的距离d(d<=1000)
输出数据
输出最小距离的最大值
样例输入
4 1
1 2 3
样例输出
3
刚开始无法理解这个题,自己试着多谢了几遍,又问的gpt才明白了,还得多练习。
`#include
include
include
using namespace std;
bool juli(int * len,int n,int m,int mid)
{
int rocknum = 0;
int st = 1;
for(int i = 2;i <= n;i++){
if(len[i]-len[st]<mid){
rocknum ++;
}
else
st = i;
}
if(rocknum > m)return false;
else return true;
}
int main()
{
int n ,m;
cin>>n>>m;
int len[n+2] = {0},a[n+2];
for(int i = 2;i <= n;i++){
cin>>a[i];
//cout<<len[i]<<endl;
len[i] = len[i-1] + a[i];
}
int l = 0,r = 1000 * 1000 + 10;
while(r-l > 1){
int mid = (l+r)/2;
if(juli(len,n,m,mid))l = mid;
else r = mid;
}
cout<<l<<endl;
}`
Problem F. 数对选择
时间限制 1000 ms
内存限制 64 MB
题目描述
给你一个长度为n的数组和一个正整数k,问从数组中任选两个数使其和是k的倍数,有多少种选法。 对于数组a1=1 , a2=2 , a3=2而言:
(a1,a2)和(a2,a1)被认为是同一种选法;
(a1,a2)和(a1,a3)被认为是不同的选法。
输入数据
第一行有两个正整数n,k。n<=1000000,k<=1000000 第二行有n个正整数,每个数的大小不超过1e9
输出数据
选出一对数使其和是k的倍数的选法个数
样例输入
5 6
1 2 3 4 5
样例输出
2
样例说明
样例解释:
a1+a5=6,a2+a4=6,都是6的倍数
所以符合条件的选法有(1,5),(2,4)
这个题我也不清楚为啥有个例子总是过不去,第一个代码是80分的,第二个是满分的
`#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 5;
int n, k;
long long a[MAXN], co[MAXN];
long long ans;
int main() {
cin >> n >> k;
for(int i = 1; i <= n; i++) {
cin >> a[i];
int num = a[i]%k;
co[num]++ ;
}
// for(int i = 0; i < k; i++) {
// cout<<co[i]<<endl;
// }
for(int i = 1; i <= k/2; i++) {
if(i == k-i){
ans += (co[i] * co[k-i])/2;
}
else
ans += (co[i] * co[k-i]);
}
cout << ans << endl;
return 0;
}`
满分
`
include
include
using namespace std;
int main() {
int n, k;
cin >> n >> k;
vector<int> remainderCount(k, 0);
long long totalCount = 0;
for (int i = 0; i < n; i++) {
int num;
cin >> num;
int remainder = num % k;
int complement = (k - remainder) % k;
totalCount += remainderCount[complement];
remainderCount[remainder]++;
}
cout << totalCount << endl;
return 0;
}
`
gpt比我强太多了。我《百度《gpt。。。
浙公网安备 33010602011771号