SDUT ACM 2013级选拔赛(部分题目)
2014-12-06 21:56
429 查看
真是没sei了,各种不在状态,又困又累,脑袋就和要炸了一样,也不知道怎么了。四个小时真是一点没浪费,真的算是重新审视了一下自己。这一阵一直乱七八糟的搞来搞去,也没点目的性,算是一直在看算法,算法也没说有多少精进,数学类型靠思维的真的感觉有点无力,反应真的很慢,感觉做题还是太少了,涉猎的面太窄,既然知道了,接下来就去做吧,时间略紧。下面进入正题:
将n个棋子摆成一条直线,编号为1到n。两个人轮流取棋子,每回合取一次且只能按照下述两种方法的一种取。
1,任取一个棋子。
2,任取两个棋子且这两个棋子的编号是连续的。
FF为了彰显高手风范总是让对方先手。现在假设两个人都足够聪明,对于给出的n,FF是否能赢。取得最后一个棋子的选手获得胜利。
are you so ben?”。
这道题我真是不知道怎么说,一开始直接没画粗来,后来想着原先做过一个圆桌铺硬币,好像是先弄的那个人赢,所以我在想是不是这道题也是这样,然后。。。你懂得,A了。若是某位大牛此时再看,你恰好会,请留言,不胜感激。
FF很好奇的想知道,对于数字x,集合中有多少个数字可以在x前面添加任意数字得到。
如,x = 123,则在x前面添加数字可以得到4123,5123等。
对于每组数据
首先输入n(1<= n <= 100000)。
接下来n行。每行一个数字y(1 <= y <= 100000)代表集合中的元素。
接下来一行输入m(1 <= m <= 100000),代表有m次询问。
接下来的m行。
每行一个正整数x(1 <= x <= 100000)。
看到n,m的取值100000是不是吓哭了?我也是这么吓哭的,而且我能说我盯着看了好长时间才看懂这道题么?
思路:用哈希做,储存每一个数值y的后面位数(例如12345,,你可以把它们分解成5,45,345,2345然后把它们当做数组的下标,然后哈希表存储的是该数字的下标有几个,12345就没必要了因为前面不能加,也不可能是它) 另外用哈希做一定要注意这个地方有一个坑!真是坑哭了,例如10086 当你%100,%1000,%10000的时候都是86,他会把这个当成三次,实际上才一次。所以一定要避开
对于每组数据,第一行输入n,接下来的n行,每行两个整数x,y(-1000 <= x,y <= 1000)代表桥的坐标。
打眼一看这是一道最小生成树的问题,和其余那些裸地差不多,只不过这道题需要你自己计算权值,而且是每个的标号都是每一行的行的行值。
否则输出 Why are you so ben? 。
这道题问的是突破1700分所需要的场次的期望,主要看的是当前分数和1700分的差值。其实在这个题里有几个比较特殊的地方,当你的分数是1700分的时候就是0场,当你的分数比1700分小的时候即差值大于0,如果此时你的加分或者加分的概率是0的话你就一直是笨蛋(这个可能有人忘了)。再说说期望的场次这么个玩意,你要怎么求,如果你的差值取余一场增加的分数的值==0,那么所得结果除以当前的加分概率即可,一开始写的是乘以数据都对,可是忽略了小数。(假设你的差值是4,你的一场加分是2,概率是0.5你怎么求,如果当前的加分概率是1的话你只需要两场就够了,也就是4/2/1,所以换成0.5的话自然是4/2/0.5了)
否则的话要+1,。
可以有一天一个小偷偷走了其中一页,FF想知道小偷偷走了那个数字。
首先一个数组n <= 2000000,代表密码本的页数。
接下来的一行有n个数,代表完整的密码本。
接下来的一行有n-1个数,代表残缺的密码本。
n的范围是2000000以内,要是开个数组的话一个个的找肯定超时,所以用快排从小到大排序后,然后比对就好。
迷之博弈
题目描述
FF喜欢博弈,今天又开始了一场博弈。将n个棋子摆成一条直线,编号为1到n。两个人轮流取棋子,每回合取一次且只能按照下述两种方法的一种取。
1,任取一个棋子。
2,任取两个棋子且这两个棋子的编号是连续的。
FF为了彰显高手风范总是让对方先手。现在假设两个人都足够聪明,对于给出的n,FF是否能赢。取得最后一个棋子的选手获得胜利。
输入
多组输入,每组一个正整数n(1<= n <= 300)。输出
若FF能胜则输出“Yeah!”,否则输出“Whyare you so ben?”。
示例输入
1 2
示例输出
Why are you so ben? Why are you so ben?
这道题我真是不知道怎么说,一开始直接没画粗来,后来想着原先做过一个圆桌铺硬币,好像是先弄的那个人赢,所以我在想是不是这道题也是这样,然后。。。你懂得,A了。若是某位大牛此时再看,你恰好会,请留言,不胜感激。
#include <stdio.h> int main() { int n; while(~scanf("%d",&n)) { printf("Why are you so ben?\n"); } return 0; }
迷之好奇
题目描述
FF得到了一个有n个数字的集合。不要问我为什么,有钱,任性。FF很好奇的想知道,对于数字x,集合中有多少个数字可以在x前面添加任意数字得到。
如,x = 123,则在x前面添加数字可以得到4123,5123等。
输入
多组输入。对于每组数据
首先输入n(1<= n <= 100000)。
接下来n行。每行一个数字y(1 <= y <= 100000)代表集合中的元素。
接下来一行输入m(1 <= m <= 100000),代表有m次询问。
接下来的m行。
每行一个正整数x(1 <= x <= 100000)。
输出
对于每组数据,输出一个数字代表答案。示例输入
3 12345 66666 12356 3 45 12345 356
示例输出
1 0 1
看到n,m的取值100000是不是吓哭了?我也是这么吓哭的,而且我能说我盯着看了好长时间才看懂这道题么?
思路:用哈希做,储存每一个数值y的后面位数(例如12345,,你可以把它们分解成5,45,345,2345然后把它们当做数组的下标,然后哈希表存储的是该数字的下标有几个,12345就没必要了因为前面不能加,也不可能是它) 另外用哈希做一定要注意这个地方有一个坑!真是坑哭了,例如10086 当你%100,%1000,%10000的时候都是86,他会把这个当成三次,实际上才一次。所以一定要避开
#include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <queue> #include <algorithm> using namespace std; int a[100010]; int hash[100010]; int main() { int n,m,x; int i,j,t; int flag; int cnt; int site,site1; while(~scanf("%d",&n)) { memset(hash,0,sizeof(hash)); for(i=0; i<n; i++) { scanf("%d",&a[i]); site=a[i]%10; cnt=10; site1=100; for(;;) { if(site==a[i]) { break; } else { if(site1!=site)//这个地方,大坑! { hash[site]++; site1=site; } cnt*=10; site=a[i]%cnt; } } } scanf("%d",&m); for(i=0; i<m; i++) { scanf("%d",&x); printf("%d\n",hash[x]); } } return 0; }
迷之节约
题目描述
FF超级有钱,最近又买了n个(1 <= n <= 300)小岛,为了能在岛之间游玩,FF决定要在岛之间修桥以保证任意两岛之间都要可达。但是FF又超级抠门,想让造桥费用最小。现在由于技术原因,一座桥的造价为两桥之间直线距离的平方。现在给你桥的坐标,让你求最小造价是多少。输入
多组输入。对于每组数据,第一行输入n,接下来的n行,每行两个整数x,y(-1000 <= x,y <= 1000)代表桥的坐标。
输出
对于每组数据输出一个整数代表最小花费。示例输入
2 1 1 1 2
示例输出
1
打眼一看这是一道最小生成树的问题,和其余那些裸地差不多,只不过这道题需要你自己计算权值,而且是每个的标号都是每一行的行的行值。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; #define inf 99999999 int map[310][310]; int dis[310]; int vis[310]; int sum; struct node { int x,y; }q[1010]; void prim(int n) { int i,j,k; int min; sum=0; memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++) dis[i]=map[1][i]; dis[1]=0; vis[1]=1; for(i=2;i<=n;i++) { min=inf; for(j=1;j<=n;j++) { if(dis[j]<min&&!vis[j]) { min=dis[j]; k=j; } } if(min==inf) break; vis[k]=1; sum+=min; for(j=1;j<=n;j++) { if(dis[j]>map[j][k]&&!vis[j]) { dis[j] = map[j][k]; } } } printf("%d\n",sum); } int main() { int n,m; int i,j; while(~scanf("%d",&n)) { for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(i==j) map[i][j]=0; else map[i][j]=inf; } } for(i=1;i<=n;i++) { scanf("%d %d",&q[i].x,&q[i].y); } for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i!=j) { m=((q[i].x-q[j].x)*(q[i].x-q[j].x) + (q[i].y-q[j].y)*(q[i].y-q[j].y)); map[i][j]=map[j][i]=m; } prim(n); } return 0; }
迷之期望
题目描述
FF一直有一个梦想,就是把CF打到紫名。可是现在有一个问题,FF并不是每场都能涨分。我们现在将这个问题简化,假设现在FF的分数为x,每一场增加a分的概率为p,增加0分的概率为1-p,现在请你计算一下FF突破1700的期望场数是多少。输入
每组输入x(0 <= x <= 1700),a (0 <= a <= 100),p (0 <= p <= 1),x,a为整数,p为浮点数。输出
每组输出输出一行。若能突破1700,则输出一个浮点数代表答案,保留小数点后三位。否则输出 Why are you so ben? 。
示例输入
1700 1 1 1699 100 1 0 0 0
示例输出
0.000 1.000 Why are you so ben?
这道题问的是突破1700分所需要的场次的期望,主要看的是当前分数和1700分的差值。其实在这个题里有几个比较特殊的地方,当你的分数是1700分的时候就是0场,当你的分数比1700分小的时候即差值大于0,如果此时你的加分或者加分的概率是0的话你就一直是笨蛋(这个可能有人忘了)。再说说期望的场次这么个玩意,你要怎么求,如果你的差值取余一场增加的分数的值==0,那么所得结果除以当前的加分概率即可,一开始写的是乘以数据都对,可是忽略了小数。(假设你的差值是4,你的一场加分是2,概率是0.5你怎么求,如果当前的加分概率是1的话你只需要两场就够了,也就是4/2/1,所以换成0.5的话自然是4/2/0.5了)
否则的话要+1,。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; int main() { int x,a,b; int n; double p; double cnt; double qw; while(~scanf("%d %d %lf",&x,&a,&p)) { if(x==1700) printf("0.000\n"); else if(x>=0&&x<1700) { if(a==0||p==0) printf("Why are you so ben?\n"); else { int b=1700-x; if(b%a!=0) cnt=b/a+1; else cnt=b/a; qw=cnt/p; //printf("%d\n",cnt); printf("%.3lf\n",qw); } } } return 0; }
迷之水题
题目描述
FF有一本密码本,每一页上有一个数字x(1 <= x <= 2000000),并且两两不相等。可以有一天一个小偷偷走了其中一页,FF想知道小偷偷走了那个数字。
输入
只有一组输入。首先一个数组n <= 2000000,代表密码本的页数。
接下来的一行有n个数,代表完整的密码本。
接下来的一行有n-1个数,代表残缺的密码本。
输出
输出一个整数代表答案。示例输入
3 1 2 3 3 1
示例输出
2
n的范围是2000000以内,要是开个数组的话一个个的找肯定超时,所以用快排从小到大排序后,然后比对就好。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; int a[2000010]; int b[2000010]; int main() { int n,i,j; int flag=0; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); for(j=1;j<=n-1;j++) scanf("%d",&b[j]); sort(a+1,a+n+1); sort(b+1,b+n); for(i=1;i<=n;i++) { if(a[i]!=b[i]) { printf("%d\n",a[i]); flag=1; break; } } if(!flag) printf("%d\n",a[i-1]); return 0; }
相关文章推荐
- 2017年5月月赛-暨中南大学暑期集训选拔赛第一场-部分题目
- SDUT_2012省赛选拔赛2 部分题目
- ORACLE数据库部分面试题目
- NYOJ之题目1058部分和问题
- LeetCode-Easy部分中标签为Two Pointers的所有题目
- 杭电上的部分题目分类
- android面试题目大全<完结部分>,android笔试题目集锦
- OWASP Juice Shop v6.4.1部分题目答案(二)
- 2014 Multi-University Training Contest 2 部分题目解题报告
- 用带余除法可以解决一切部分分式的题目
- 面试软件测试 智力题题目与部分答案
- 2014 Multi-University Training Contest 6 部分题目解题报告
- 昨晚看《天才知道》3进2的一个java基础题目有感:java是一种跨平台语言,它组成的2个部分是什么
- 并查集部分题目
- OJ终于到了300道,附赠部分题目的错误记录
- 庞果英雄会部分题目解答
- PKU动态规划部分题目列表
- 2013年5-5阿里巴巴暑期实习招聘笔试题目及部分答案
- 2017年上海金马五校程序设计竞赛(网上资格赛)部分题目题解
- 剑指offer算法编程题目部分汇总(解法略)