首先给个链接给大家,让大家慢慢看题http://acm.bnu.edu.cn/v3/problem.php#page=1726
题目1:无聊的游戏
比赛的时候不敢对数学题下手是个巨大的问题。题目很明显给那么大的n,k(最大10^9)。除了数学规律没有其他方法。首先就是对n分类,分奇偶。多算几个就边弄边猜
下面讨论:n为奇数时,当k%4=1或者2时,B获胜,否则A获胜
n为偶数时,当k为奇数,为平局输出F;当k%4=2时,输出B,否则输出A
其实吧,这种题在比赛的时候,派个队友数学好的,把n,k=1,2,3,4,5,6的各种情况列举一下,细心点,总结规律。很好做的
不多说,代码如下:
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>k;
if (n%2)
{
if (k%4==1||k%4==2) puts("B");
else puts("A");
}
else
{
if (k%2==1) puts("F");
else if (k%4==2) puts("B");
else puts("A");
}
}
return 0;
}
题目2:萌萌哒BY哥哥
这个没啥好说的,大家去翻组合数学的书吧,错排公式:Xn=(n-1)(X(n-1)-X(n-2))。唯一的坑点是不能用int要用long long
题目3:Monty Hall Problem
数学好的队友做的,思路如下:
原来一共n扇门,其中有n-1扇门后面是山羊,只有1扇门后面是汽车。因此,初始情况选择山羊的概率是(n-1)/n,汽车的概率是1/n
第一次选择之后,已经揭晓了n-2个山羊,由题意知,必须改选门,则:初始选择山羊的话,就改成了选择汽车,因此答案就是(n-1)/n
题目4:计算题
坑点1:可以为空,即长度为0时输出0。因此必须用gets读入
坑点2:每次累加时要给ans%p,不然可能越界
题目5:冠名争夺战
很好的博弈题:答案出人意料的简单:永远都是Bill will lose HAHA
解释:反证法:(注意到决策次数不是把所有的石子都选择完,而是只选择几个)(证明思想非常类似于取石子的博弈)
假设后手有必胜策略,即取到Ai颗石子使得在剩余的所有石子中,先手找不到一个石子可以打败Ai。那么在先手的第一次任意选择时,先手就可以选择Ai颗石子使自己获胜。因此,无论游戏怎样设计,必然都是先手获胜
题目6:柯南的精灵
数学题:至今没找到规律,希望有大神能够教教我
题目7:疯狂睡眠
标准贪心:以各睡眠时间的结束点由低到高进行排序,若相同,则按照起始点的由低到高排序
排序后,依次按顺序逐渐选择即可。代码如下
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;
#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define For1(i,a,b) for (i=a;i<b;i++)
#define For2(i,a,b) for (i=a;i<=b;i++)
#define Dec(i,a,b) for (i=a;i>b;i--)
#define Dec2(i,a,b) for (i=a;i>=b;i--)
#define Sca_d(x) scanf("%d",&x)
#define Sca_s(x) scanf("%s",x)
#define Sca_c(x) scanf("%c",&x)
#define Sca_f(x) scanf("%f",&x)
#define Sca_lf(x) scanf("%lf",&x)
#define Sca_lu(x) scanf("%I64d",&u)
#define Sca_ld(x) scanf("%I64d",&x)
#define Fill(x,a) memset(x,a,sizeof(x))
#define inf 0x3f3f3f3f
struct node
{
int x,y;
}que[10005];
int cmp(const void *a,const void *b)
{
struct node *c=(node *)a;
struct node *d=(node *)b;
if (c->x!=d->x) return c->y - d->y;
return c->x - d->x;
}
int main()
{
//input;
int t,n,i,j,k,ans,cur;
cin>>t;
while(t--)
{
Fill(que,0);
cin>>n;
For2(i,1,n)
Sca_d(que[i].x),Sca_d(que[i].y);
qsort(que+1,n,sizeof(que[0]),cmp);
cur=i=ans=0;
while(i<n)
{
i++;
if (cur<que[i].x)
{
cur=que[i].y;
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}
题目8:First Contact
简单0-1背包模型:却浪费了1个小时,还需对经典问题多加总结与训练
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;
#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define For1(i,a,b) for (i=a;i<b;i++)
#define For2(i,a,b) for (i=a;i<=b;i++)
#define Dec(i,a,b) for (i=a;i>b;i--)
#define Dec2(i,a,b) for (i=a;i>=b;i--)
#define Sca_d(x) scanf("%d",&x)
#define Sca_s(x) scanf("%s",x)
#define Sca_c(x) scanf("%c",&x)
#define Sca_f(x) scanf("%f",&x)
#define Sca_lf(x) scanf("%lf",&x)
#define Sca_lu(x) scanf("%I64d",&u)
#define Sca_ld(x) scanf("%I64d",&x)
#define Fill(x,a) memset(x,a,sizeof(x))
#define inf 0x3f3f3f3f
int dp[1005];
int book[1005];
int aa[1005];
int bb[1005];
int main()
{
//input;
int a,b,n,x,y,i,j,t;
cin>>t;
for(int Case=1;Case<=t;Case++)
{
Fill(dp,0);Fill(aa,0);Fill(bb,0);Fill(book,0);
cin>>a>>b>>n;
For2(i,1,n) cin>>aa[i];
For2(i,1,n) cin>>bb[i];
/*For2(i,1,n)
For2(j,1,i)
if (aa[i]>aa[j]||(aa[i]==aa[j]&&bb[i]<bb[j]))
{
int temp;
temp=aa[i];aa[i]=aa[j];aa[j]=temp;
temp=bb[i];bb[i]=bb[j];bb[j]=temp;
}
*/
for(i=1;i<=n;i++)
for(j=a;j>=aa[i];j--)
dp[j]=max(dp[j],dp[j-aa[i]]+bb[i]);
printf("Case #%d: %s\n",Case,dp[a]>=b?"YES":"NO");
//printf("%d\n",dp[a]);
}
return 0;
}
题目9:平面切割者
本来比赛的时候可以自豪一番,第一次就把公式推理出来了,坑爹的n=0!
首先可以画图计算:n=0时ans=2,n=1时ans=4,n=2时ans=8,n=3时ans=13,n=4时ans=19(这个画图比较费劲。。圆要画得很大)
接下来是推理:把大圆和小圆中间的圆环看作一个部分,每次增加一根线,多增加两个区域
把小圆看作另外一个部分,每次增加一根线,多增加i个区域,其中i是当前添加的是第i根线
因此,在O(n)时间推得,ans[i]=ans[i-1]+i+2。初始值ans[0]=0,ans[1]=4,递推式从i=1开始计算
题目10:拯救辣条
这么小的数据,简单粗暴的DFS即可!注意:题中求与Bi不同的组数,因此输出ans-1
代码如下:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;
#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define For1(i,a,b) for (i=a;i<b;i++)
#define For2(i,a,b) for (i=a;i<=b;i++)
#define Dec(i,a,b) for (i=a;i>b;i--)
#define Dec2(i,a,b) for (i=a;i>=b;i--)
#define Sca_d(x) scanf("%d",&x)
#define Sca_s(x) scanf("%s",x)
#define Sca_c(x) scanf("%c",&x)
#define Sca_f(x) scanf("%f",&x)
#define Sca_lf(x) scanf("%lf",&x)
#define Sca_lu(x) scanf("%I64d",&u)
#define Sca_ld(x) scanf("%I64d",&x)
#define Fill(x,a) memset(x,a,sizeof(x))
#define inf 0x3f3f3f3f
const int maxn=10;
int ans;
int t,n,a[maxn],b[maxn],c[maxn];
void dfs(int cur)
{
int i,j,k;
if (cur==n+1)
{
ans++;
//For2(j,1,n)
// printf("%d%c",c[j],j==n?'\n':' ');
return;
}
For2(i,0,a[cur])
{
c[cur]=i;
if (cur==1) dfs(cur+1);
else if ((b[cur]>b[cur-1]&&c[cur]>c[cur-1])||(b[cur]==b[cur-1]&&c[cur]==c[cur-1])||(b[cur]<b[cur-1]&&c[cur]<c[cur-1]))
dfs(cur+1);
}
return;
}
int main()
{
//input;
int i,j,k;
cin>>t;
while(t--)
{
cin>>n;
For2(i,1,n) cin>>a[i];
For2(i,1,n) cin>>b[i];
ans=0;
dfs(1);
cout<<ans-1<<endl;
}
return 0;
}
题目11:顽皮的字母
字母顽皮的我都想打人了。但学到了一个很好的像是DP的思想,我当前的判断值只跟前面已经做过的判断比较
代码如下:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;
#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define For1(i,a,b) for (i=a;i<b;i++)
#define For2(i,a,b) for (i=a;i<=b;i++)
#define Dec(i,a,b) for (i=a;i>b;i--)
#define Dec2(i,a,b) for (i=a;i>=b;i--)
#define Sca_d(x) scanf("%d",&x)
#define Sca_s(x) scanf("%s",x)
#define Sca_c(x) scanf("%c",&x)
#define Sca_f(x) scanf("%f",&x)
#define Sca_lf(x) scanf("%lf",&x)
#define Sca_lu(x) scanf("%I64d",&u)
#define Sca_ld(x) scanf("%I64d",&x)
#define Fill(x,a) memset(x,a,sizeof(x))
#define inf 0x3f3f3f3f
char s[1000000],ans[1000000];
int main()
{
//input;
int i,j,k,l,t,flag,start,cur;
cin>>t;
while(t--)
{
cin>>s;
l=strlen(s);
cur=1;
ans[0]=s[0];
for(i=1;i<l;i++)
{
if (s[i]%2)//当前字母为 a,c,e,g……
{
if (s[i]+1==ans[cur-1]) cur--;//满足ab,cd……把ans的已存的字母删除
else ans[cur++]=s[i];//添加当前字母
}
else//当前字母为b,d,f,h……
{
if (s[i]-1==ans[cur-1]) cur--;
else ans[cur++]=s[i];
}
}
ans[cur]='\0';
if (!cur) puts("sad!");//所有的字母已经消除
else printf("%s\n",ans);
}
return 0;
}