第一题(宝物筛选)
评析:多重背包的二进制优化
#include<bits/stdc++.h>
using namespace std;
int n,W;
int f[40005];
int v[2005],w[2005];
int main()
{
cin>>n>>W;
int cnt=0;
int vi,wi,mi;
for(int i=1;i<=n;i++)
{
cin>>vi>>wi>>mi;
int k=1;
while(k<=mi)
{
cnt++;
v[cnt]=vi*k;
w[cnt]=wi*k;
mi-=k;
k*=2;
}//二进制拆分
if(mi>0)
{
cnt++;
v[cnt]=vi*mi;
w[cnt]=wi*mi;
}
}//特殊情况判断
for(int i=1;i<=cnt;i++)
for(int j=W;j>=w[i];j--)
f[j]=max(f[j],f[j-w[i]]+v[i]);//转移方程
cout<<f[W];
return 0;
}
第二题(尴尬的数字)
评析:我的想法就是枚举,但是暴力就超时,看了题解的大佬,优化就OK了。
#include<bits/stdc++.h>
using namespace std;
long long ans2,ans3;
int map2[100000],map3[100000],l2,l3;
char t[100000],s[100000];
int main()
{
scanf("%s",t);
l2=strlen(t);
for(int i=0;i<l2;i++)
{
t[i]-='0'-1;
map2[i]=t[i]-1;
}//大佬的这一处细节要注意
scanf("%s",s);
l3=strlen(s);
for(int i=0;i<l3;i++)
{
s[i]-='0'-1;
map3[i]=s[i]-1;
}
for(int i=0;i<l2;i++)
{
for(int j=0;j<l3;j++)
{
int x=map3[j];
for(int k=0;k<=2;k++)
{
if(map2[i]==1) map2[i]=0; else map2[i]=1;//更改
map3[j]=k;//继承
for(int l=0;l<l2;l++)
{
ans2+=map2[l];
ans2*=2;
}//换算十进制
ans2/=2;
for(int l=0;l<l3;l++)
{
ans3+=map3[l];
ans3*=3;
}//换算十进制
ans3/=3;
if(map2[i]==1) map2[i]=0; else map2[i]=1;//更改
map3[j]=x;//继承
if(ans2==ans3)//比较
{
printf("%d",ans2);
return 0;
}
ans2=ans3=0;
}
}
}
}
第三题(小卡和质数)
评析:怎么样的两个数异或值1呢?显然是二进制下只有末尾不同的数,要满足这个条件,需要两数奇偶性不同(思考这个条件是因为考虑到质数特殊的奇偶性质),则两个质数为一奇一偶。偶数中只有2是质数,而易知在其它质数中,只有 3 和 2 的异或值为 1。最终得到:两个质数只能是 3 和 2。明白原理就简单了。
#include<bits/stdc++.h>
using namespace std;
int n,x,y;
int main()
{
cin>>n;
while(n--)
{
cin>>x>>y;
if ((x==1 && y==2) || (x==2 && y==1)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}