本次测试成绩如下:
哈哈,我考了100分,拿了个第34名!
来这次考试的看看题目:
第一题:小X与游戏 (game)
(Input: game.in, Output: game.out)
时间限制: 1 s 空间限制: 256 MB
题目描述
小X和小Y正在玩一个游戏,这个游戏是这样的:桌上放着n叠卡片,每叠恰好有两张。每张卡片有一个分数。小X为先手,双方轮流操作。轮到一方操作时,他可以选择取走某一叠卡片顶端的那一张(即:若这一叠还剩2张则取走上面的一张,否则取走下面的一张),并获得它的分数。他也可以选择不取。若卡片取完了、或者双方都选择不取卡片,那么游戏结束。
小X和小Y都希望自己的分数减去对方的分数尽可能大。现在假设小X和小Y都绝顶聪明,总是做出对自己最有利的决策,请算出游戏结束时小X比小Y高多少分。
输入
从文件 game.in
中读入数据。
输入的第一行包含一个正整数n。
接下来n行,每行包含2个用空格隔开的非负整数a[i], b[i],分别表示第i叠中放在上面、下面的卡片的分值。
输出
输出到文件 game.out
中。
输出仅有一行包含一个整数,表示游戏结束时小X比小Y高多少分。如果小X的分数比小Y低则输出一个负数。
样例输入 复制
2 1 2 4 3
样例输出 复制
1
数据范围限制
对于30%的数据,1<=n<=1000, b[i]=0
对于70%的数据,1<=n<=1000
对于100%的数据,1<=n<=100000, 0<=a[i], b[i]<=1000000
提示
样例解释
小X取走4,小Y取走3,小X不取,小Y不取,游戏结束。4-3=1
考试的时候打了个表,结果0分:
#include<bits/stdc++.h>
using namespace std;
long a[1000001],b[1000001],s,p[1000001],mx,n;
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i];
}
cout<<1;
}
最后听别人讲题,恍然大悟,这是AC代码:
#include<bits/stdc++.h>
using namespace std;
int m,n,x[1000001],y[1000001],z[1000001],f1,f2,l;
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x[i],&y[i]);
if(x[i]>y[i])
{
z[++l]+=x[i];
z[++l]+=y[i];
}
}
sort(z+1,z+l+1);
for(int i=1;i<=l/2;i++)
{
f1+=z[i*2];
f2+=z[i*2-1];
}
printf("%d",f1-f2);
}
第二题:小X与队列 (queue)
(Input: queue.in, Output: queue.out)
时间限制: 1 s 空间限制: 256 MB
题目描述
小X正和同学们做列队的练习。
有n名同学排成一路纵队,编号为i的同学排在从前往后数第i个位置上,即:初始时的队列为1, 2, 3, ..., n。
接下来小X会发出若干条指令,每条指令形如“请编号为x的同学排到最前面来”。(例如:若当前时刻的队列为5, 4, 3, 2, 1,发出一条x=2的指令后,队列变成了2, 5, 4, 3, 1。)
小X发出了很多很多指令,同学们晕头转向不知道该怎么排列。于是就请你算一算,执行完这些指令后,队列应该变成什么样?
输入
从文件 queue.in
中读入数据。
第一行两个用空格隔开的正整数n和m,分别表示人数和指令数。
第二行m个用空格隔开的正整数x[i],按顺序表示每次指令的x值。
输出
输出到文件 queue.out
中。
输出仅有一行包含n个正整数,相邻两个数之间用一个空格隔开,表示执行完所有指令后的队列。
样例输入 复制
4 3 2 3 2
样例输出 复制
2 3 1 4
数据范围限制
对于30%的数据,1<=n,m<=1000
对于另外30%的数据,n=m,且1~n每个数在x[i]中恰好出现一次。
对于100%的数据,1<=n,m<=100000
提示
样例解释
第一条指令前:1 2 3 4
第一条指令后(x=2):2 1 3 4
第二条指令后(x=3):3 2 1 4
第三条指令后(x=2):2 3 1 4
一开始样例对了,但是oj评测时却运行时错误了,0分:
#include<bits/stdc++.h>
using namespace std;
long s[1000001],b[1000001];
int main()
{
freopen("queue.in","r",stdin);
freopen("queue.out","w",stdout);
long n,m,k,r=0;
cin>>n>>m;
long a[n+1];
for(long i=1;i<=n;i++)
{
a[m+i]=i;
}
for(long i=1;i<=m;i++)
{
cin>>a[i];
if(s[a[i]]==1)
{
a[i]=0;
continue;
}
s[a[i]]++;
}
for(long i=1;i<=n+m;i++)
{
b[a[i]]++;
if(b[a[i]]==1&&a[i]!=0)
cout<<a[i]<<" ";
}
}
出成绩后一直搞不懂原因,之后听别人讲题时,发现是数组越界,然后代码复杂度太高了,改进之后成功AC
修改后:
#include<bits/stdc++.h>
using namespace std;
int b[1000001],a[1000001];
int main()
{
int n,m,k;
freopen("queue.in","r",stdin);
freopen("queue.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=m;i++)
cin>>b[i];
for(int i=m;i>=1;i--)
{
if(!a[b[i]])
{
a[b[i]]=1;
cout<<b[i]<<" ";
}
}
for(int i=1;i<=n;i++)
{
if(!a[i])
cout<<i<<" ";
}
}
第三题:小X分砖块(brick)
(Input: brick.in, Output: brick.out)
时间限制: 1 s 空间限制: 256 MB
题目描述
小 X 喜欢跟着爸爸跑到建筑工地上去。
这天,小 X 看到一排砖,每块要么是白色的(0),要么是黑色的(1)。小 X 想把这排砖分成若干非空段,使得每段白砖和黑砖块数的比例相同。
当然,小 X 可以直接把整排砖作为一段,那就太简单了。为了增加难度,小 X 想知道最多能分成多少段,例如:
100011 = 10 + 0011(即样例 1,最多分成 2 段,比例为 1:1);
0001110000000001 = 0001 + 11000000 + 0001(即样例 2,最多分成 3 段,比例为 3:1)。
小 X 百思不得其解,希望你帮帮他。
输入
从文件 brick.in
中读入数据。
第一行包含一个整数 N。我们将用 N 行来描述这排砖,初始时这排砖为空。
接下来 N 行,每行包含用一个空格隔开的两个整数 Ki,Ci(Ci 只可能是 0 或 1),表示在上一行描述完后尾部又有了 Ki 块颜色为 Ci 的砖。
输出
输出到文件 brick.out
中。
第一行包含一个整数,表示最多能分成的段数。
样例输入 复制
样例输入1 3 1 1 3 0 2 1 样例输入2 4 3 0 3 1 9 0 1 1
样例输出 复制
样例输出1 2 样例输出2 3
数据范围限制
对于 30%的数据,N=1。
对于 60%的数据,所有 Ki 均相等。
对于 100%的数据,1≤N≤100000,1≤Ki≤1000000000,砖的总块数不超过 1000000000。
这道题考试时丝毫看不懂,所以就随便打了个表,毫无悬念,又是0分的:
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long a,b,c;
freopen("brick.in","r",stdin);
freopen("brick.out","w",stdout);
cin>>a;
for(long long i=1;i<=a;i++)
{
cin>>b>>c;
}
cout<<a-1;
}
这道题听老师讲了还是不明白,所以没改对!如果有谁会做,请评论留言!
而且,我们班没有一个做出来的!
第四题:小X与神牛 (hamming)
(Input: hamming.in, Output: hamming.out)
时间限制: 1 s 空间限制: 256 MB
题目描述
小X在野外遇到了一种神奇的牛,并将其命名为“神牛”。
神牛都长着B只角,B只角从左到右在头顶上排成一排。每只角上都标着数字,不是0就是1。小X将每头神牛的B只角上的数字从左到右依次取出,组成一个只含0或1的B位二进制数。小X将这个二进制数转化为十进制,用这个十进制数来代表一头神牛,这个十进制就是这头神牛的编号。
神牛们之间的关系是很微妙的,如果两头神牛的第i只角上的数字不同,则称这两头神牛的第i只角是不一样的。如果两头神牛不同的角的数目大于等于D,则称这两头神牛是友好的。比如当B=8,D=2时,
这两头神牛的第2和第3只角不同(x指向的位置),不同的角的数目为2,所以这两头神牛是友好的。
现在小X向你求助:请找出N头神牛,使得任意两头神牛都是友好的,并将这N头神牛的编号按从小到大排序后依次输出。如果有多种符合条件的解,那么排在越前面的牛的编号越小越好。
输入
从文件 hamming.in
中读入数据。
输入仅有一行包含3个用空格隔开的正整数,分别表示 N, B, D。
输出
输出到文件 hamming.out
中。
输出仅有一行包含N个非负整数,相邻两个数之间用一个空格隔开,表示N头神牛的编号。如果有多解,你的程序要输出这样的解:越前面的牛的编号越小越好。
样例输入 复制
3 5 3
样例输出 复制
0 7 25
数据范围限制
对于30%的数据,1<=D<=B<=8,1<=N<=3
对于另外10%的数据,D=1
对于另外30%的数据,D=2
对于100%的数据,1<=D<=B<=8, 1<=N<=16
数据保证有解。
提示
样例输入2
16 7 3
样例输出2
0 7 25 30 42 45 51 52 75 76 82 85 97 102 120 127
样例2解释
每头神牛都长着7只角,若两头神牛不同的角的数目大于等于3,则这两头神牛是友好的。现在要找出16头相互都友好的神牛。
答案是0000000, 0000111, 0011001, 0011110, 0101010, 0101101, 0110011, 0110100, 1001011, 1001100, 1010010, 1010101, 1100001, 1100110, 1111000, 1111111,转化为十进制就是0 7 25 30 42 45 51 52 75 76 82 85 97 102 120 127
这题一下子就AC了:
#include<bits/stdc++.h>
using namespace std;
int n,b,d,h,s[1000001];
bool q;
bool dg(int x,int y)
{
int t=0;
for(int i=1;i<=8;i++)
if(((x^y)>>(i-1))&1)
t++;
if(t>=d)
return 1;
return 0;
}
int main()
{
freopen("hamming.in","r",stdin);
freopen("hamming.out","w",stdout);
scanf("%d%d%d",&n,&b,&d);
h=-1;
for(int i=1;i<=n;i++)
{
q=1;
while(q)
{
q=0;
h++;
for(int j=1;j<=i-1;j++)
if(!dg(s[j],h))
{
q=1;
break;
}
}
printf("%d ",h);
s[i]=h;
}
}
OK!今天的比赛分析就讲到这里,下次再见!
最后说一声抱歉:因为最近的学业任务比较繁重,没时间给大家更新oj做题情况,让大家久等了!
Bye!