A 空间
256 * 1024 * 1024 * 8 / 32
B 卡片
答案 3181
#include<bits/stdc++.h>
using namespace std;
int s[10];
bool is_t(int a)
{
while(a)
{
int x = a % 10;
--s[x];
if(s[x] < 0) return true;
a/=10;
}
return false;
}
int main()
{
int cnt = 0;
for(int i = 0; i <= 9; i++) s[i] = 2021;
for(int i = 1; i ; i++)
{
if(is_t(i))
{
break;
}
cnt++;
}
cout<<cnt<<endl;
return 0;
}
C 直线
答案 40216
求出没两个点间的斜率和截距
set 去重
#include<bits/stdc++.h>
using namespace std;
typedef pair<double,double> PII;
set <PII> s;
int x = 20,y = 21;
int main()
{
for(int i = 0; i < x; i++)
{
for(int j = 0; j < y; j++)
{
for(int i1 = 0; i1 < x; i1++)
{
for(int j1 = 0; j1 < y; j1++)
{
if(i == i1 || j == j1) continue;
double k =(j1-j)*1.0/((i1-i)*1.0);
double k1 = (i1*j-j1*i)/(i1*1.0-i*1.0);
s.insert({k,k1});
}
}
}
}
cout<<s.size()<<endl;
return 0;
}
D 货物摆放
答案 2430
3个数相乘得到一个数其肯定是其约数
找所有约数
枚举
解决
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
vector<LL>v;
void is_v(LL s)
{
for(int i = 1; i <= s/i; i++)
{
if(s % i == 0) {
v.push_back(i);
if(s / i != i) v.push_back(s/i);
}
}
}
int main()
{
LL s = 2021041820210418;
is_v(s);
int cnt = 0;
for(int i = 0; i < (int)v.size(); i++)
{
for(int j = 0; j < (int)v.size(); j++)
{
for(int k =0; k < (int)v.size(); k++)
{
if(v[i]*v[j]*v[k] == s) cnt++;
}
}
}
cout<<cnt<<endl;
return 0;
}
E 路径
填空题floyd硬跑啦太好想
#include<bits/stdc++.h>
using namespace std;
const int N = 3000;
int s[N][N];
int gcd(int a,int b)
{
if(a % b == 0) return b;
else gcd(b,(a%b));
}
void floyd()
{
int n = 2021;
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
if(s[i][k] == 0x3f3f3f3f) continue;
for(int j=1;j<=n;j++)
{
if(s[k][j]==0x3f3f3f3f) continue;
s[i][j]=min(s[i][j],s[i][k]+s[k][j]);
}
}
}
}
int main()
{
memset(s,0x3f3f3f3f,sizeof s);
for(int i = 1; i <=2021; i++)
{
for(int j = i+1; j <= i+21; j++)
{
int d = i*j/gcd(j,i);
s[i][j] = d;
s[j][i] = d;
}
}
floyd();
cout<<s[1][2021]<<endl;
return 0;
}
第二种方法
#include<stdio.h>
int A[10000];
int min(int i, int n) {
return i < n ? i : n;
}
int qwe(int i, int n)
{
int t, k, l;
t = i > n ? i : n;
k = i < n ? i : n;
while (k)
{
l = t % k;
t = k;
k = l;
}
return (i * n) / t;
}
int main() {
int i, j;
for (i = 1;i <= 22;i++) A[i] = i;
for (i = 23;i <= 2021;i++){
A[i] = qwe(i, i - 21)+A[i-21];
}
for (i =23;i<=2021;i++) {
for (j = 1;j <= 21;j++) {
A[i] = min(A[i], A[i-j] + qwe(i,i-j));
}
}
printf("%d\n", A[2021]);
return 0;
}
F 时间显示
提交点
模拟 注意1s == 1000ms
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
LL ms;
cin>>ms;
LL s = ms/1000;
LL min = s/60%60;
LL h = s/3600%24;
printf("%02d:%02d:%02d\n",h,min,s%60);
return 0;
}
G 砝码称重
提交点
1.比赛交的dfs骗分的哈哈哈(10分)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int s[105];
set<int> se;
bool st[N];
int n;
void dfs(int step,int u)
{
if(step > n) return;
if(step == n)
{
if(u == 0) return;
u = abs(u);
se.insert(u);
}
for(int i = 0; i < n; i++)
{
if(st[i]) continue;
st[i] = 1;
dfs(step + 1,u + s[i]);
dfs(step + 1,u - s[i]);
st[i] = 0;
dfs(step + 1, u);
}
}
int main()
{
cin>>n;
for(int i = 0; i < n; i++) cin>>s[i];
dfs(0,0);
set<int>::iterator i;
cout<<se.size()<<endl;
return 0;
}
正解
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int s[105],dp[105][N];
bool st[N];
int n,MAX;
int main()
{
cin>>n;
for(int i = 1; i <= n; i++) {
cin>>s[i];
MAX += s[i];
}
dp[1][s[1]] = 1;
for(int i = 2; i <= n; i++)
{
for(int j = 1; j <= MAX; j++)
{
dp[i][j] = dp[i-1][j];
}
for(int j = 1; j <= MAX; j++)
{
if(dp[i-1][j])
{
dp[i][j+s[i]] = 1;
dp[i][abs(j-s[i])] = 1;
}
}
dp[i][s[i]] = 1;
}
int ans = 0;
for(int i = 1; i <= MAX; i++)
{
if(dp[n][i])
ans++;
}
cout<<ans<<endl;
return 0;
}
1.选定一个数时
dp[s[1]] = 1;
选定
2.选定i个数时能构造什么数
dp[i][j] = dp[i-1][j]; 上一层被标记的都可以选
for(int j = 1; j <= MAX; j++)
{
dp[i][j] = dp[i-1][j];
}
dp[i-1][j]==1
1 dp[i][j+s[i]]=1;
2 dp[i][abs(j-s[j])]=1
for(int j = 1; j <= MAX; j++)
{
if(dp[i-1][j])
{
dp[i][j+s[i]] = 1;
dp[i][abs(j-s[i])] = 1;
}
}
单独这个数当然也可
dp[i][x] = 1;
dp[i][x]=1
最后结果为dp[n]这一层被标记的数