Summary
一大波兴安熊🐻正在靠近,请做好预防准备。。。
此外还发现了一些神奇的图案,哈哈 = ̄ω ̄= 图片11:36更新
2020.01.03 16:09 更新一个图片 QWQ
Information
No. | Title | AC/Submit |
---|---|---|
A | teacher Li | 56/224 |
B | Find different | 113/305 |
C | 和为K–二进制枚举 | 143/468 |
D | 陈老师加油-二进制枚举 | 125/155 |
E | 纸牌游戏-二进制-搜索 | 124/161 |
F | 权利指数 | 63/135 |
G | 趣味解题 | 46/60 |
Problem A: teacher Li (643) [56/224]
Tips
和B题的处理方式差不多,不过要按位异或
注意输出格式多组之间有一个额外的换行
之前注释里写成取短的字符串 了 感谢大佬 jwMM 提出的问题 ヾ(•ω•`)o
提供一组毒数据,你的程序能过吗?
温馨提示:这组数据过不去不会影响在你OJ上AC
Input
3
interesting
apple
abcdefg
apple
interesting
Output
3
abcdefg
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,cnt=0;
char ans[30]={0};
char tmp[31];
while(cin>>n)
{
memset(ans,0,sizeof(ans));
for(int i=0;i<2*n-1;i++)
{
cin>>tmp;
for(int j=0;j<strlen(tmp);j++)//异或以后输入字符串为准避免截断长字符串
{
ans[j]^=tmp[j];
}
}
printf("Scenario #%d\n%s\n\n",++cnt,ans);//别忘了加Scenario 最后还要一个换行
}
return 0;
}
Problem B: Find different (1172) [113/305]
Tips
神奇的算法,通过不断异或留下单独的数字
异或运算对同一数两次异或效果抵消,对0异或等于本身
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,tmp,ans;
while(scanf("%d",&n)!=-1)
{
ans=0;
while(n--)
{
scanf("%d",&tmp);
ans^=tmp;
}
printf("%d\n",ans);
}
return 0;
}
Problem C: 和为K–二进制枚举 (1205) [143/468]
Tips
比较基础的二进制枚举
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,k,num[20],sum;
while(cin>>n>>k)
{
for(int i=0;i<n;i++)cin>>num[i];
for(int i=0;i<1<<n;i++)
{
sum=0;
for(int j=0;j<n;j++)
{
if(i&1<<j)sum+=num[j];
}
if(sum==k)
{
printf("Yes\n");
k=-1;
break;
}
}
if(k!=-1)printf("No\n");
}
return 0;
}
Problem D: 陈老师加油-二进制枚举 (1505) [125/155]
Tips
最后车没油了说明最后一次经过的一定是路口
这样只需要枚举前14步就可以了
如果枚举15步要考虑中途没油的情况不成立
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t,gas=0,cross=0,oil,ans=0;
cin>>t;
for(long long i=0;i<1<<14;i++)
{
oil=t;
gas=cross=0;
for(int j=0;j<14;j++)
{
if(i&1<<j)//1-加油站 0-路口
{
gas++;
oil*=2;
}
else
{
cross++;
oil--;
if(oil<0)break;
}
}
if(cross==9&&gas==5&&oil==1)ans++;//最后一步消耗1L油所以剩下1L 之前经过9个路口 5个加油站
}
cout<<ans;
return 0;
}
Problem E: 纸牌游戏-二进制-搜索 (1518) [124/161]
Tips
简单的二进制枚举 dfs也可以
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,p,sum,ans=0,num[20];
cin>>n>>p;
for(int i=0;i<n;i++)cin>>num[i];
for(int i=0;i<1<<n;i++)
{
sum=0;
for(int j=0;j<n;j++)
{
if(i&1<<j)sum+=num[j];
}
if(sum==p)ans++;
}
cout<<ans;
return 0;
}
Problem F: 权利指数 (1641) [63/135]
Tips
二进制枚举团体成员,判断团体是否为“获胜联盟”
再依次计算各成员是否为“关键加入者”
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t,n,p,sum,ans=0,num[20],winp,ap;
cin>>t;
while(t--)
{
int ans[20]={0};
ap=0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>num[i];
ap+=num[i];
}
for(int i=0;i<1<<n;i++)
{
winp=0; //小团体的票数和
for(int j=0;j<n;j++)
{
if(i&1<<j)
{
winp+=num[j];
}
}
if(winp>ap/2) //是获胜联盟
{
for(int j=0;j<n;j++)
{
if(i&1<<j&&winp-num[j]<=ap/2) //是关键加入者
{
ans[j]++;
}
}
}
}
for(int i=0;i<n;i++)
{
if(i!=0)cout<<" "; //本题行尾有空格会报PE
cout<<ans[i];
}
cout<<endl;
}
return 0;
}
Problem G: 趣味解题 (1285) [46/60]
Tips
这个题概率没算明白是真的没法做
偷偷的看了一眼隔壁大佬的博客找到的概率算法
如果这道题三个人都做不出来才算团队做不出来,否则按可以做出计算
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,x,t,ts;
double gl[3][13],tmp,ans,ac[13];
cin>>t;
while(t--)
{
ans=0;
cin>>n;
for(int i=0;i<n;i++)cin>>gl[0][i];
for(int i=0;i<n;i++)cin>>gl[1][i];
for(int i=0;i<n;i++)cin>>gl[2][i];
for(int i=0;i<n;i++)
{
ac[i]=1-(1-gl[0][i])*(1-gl[1][i])*(1-gl[2][i]);
}
cin>>x;
for(int i=0;i<1<<n;i++)
{
tmp=1; //一种情况的概率
ts=0; //AC的题目数
for(int j=0;j<n;j++)
{
if(i&1<<j)
{
tmp*=ac[j];
ts++;
}
else tmp*=1-ac[j];
}
if(ts==x)
{
ans+=tmp;
}
}
printf("%.4f\n",ans);
}
return 0;
}