SCPC / ACM2015国庆培训正式赛
2015-10-05 12:11
344 查看
题目链接:
这是一道水题,代码很简单。
绝对值可以使用if大于0进行判定,尽量少使用math.h的东西。
这道题先输入拦截高度,对于每颗导弹的高度后面已经不需要了,所以这里连数组都不需要,直接一个扫过去统计就行了。
这个题可以用模拟,就是用两个数记录,一个是记录当前最大值,扫到后一个比他小就跳过,相同就用另一个变量count+1,比他大就替换最大值,并且count重新为0就行了。代码这里就没写了。
另一种方法是用排序,c语言课本上有冒泡排序的代码,这里有一种更方便的快速的排序方法,是c++STL里面的东西,可以直接使用。
这里要求从大到小排序,所以手写自定义比较函数cmp, 自定义排序规则。这个同样可用于结构体排序。
顺便吐槽某出题人的错误数据,吓得我以为一段时间没摸代码,排序都不会了。
这个题并没有什么坑的地方,直接scanf %s就行了。
这个题我觉得坑的地方是在于目标点坐标可以为负,错了4遍的我还在已经把某快递吐槽了千万遍了。
typedef是用来定义别名,减少代码量,c语言书上会讲。
1<< i是求1*2^i,尽量少用log函数,至于原因以后吃亏了就知道了。
这个题目要求最少刀数,就像切豆腐一样,1*4的平面豆腐可以切成两个1*2的,再把这两个1*2的叠起来再切一刀,所以只需要求二分就行了,别问我怎么这么坑的切法,问快递去,我以为那个豆腐放在那里不能叠呢。
很多同学这道题超时吧?可以算一下,如果我每次从第一个刷到第20000个,再刷这么多次(这就是题目给的最大数据量,但是一般后台都会出这么死变态的数据),那么就要算10^10次,给的时间是1s,能算10^8次,所以TLE的摸头不哭。
这里比较套模版的是用线段树做,那个他复杂,这里给一个简单的代码。
我用三个数组分别存在每次刷墙的起点终点和次数。那么每次就等于上次刷的次数加这个点作为起点的次数和减去这个点作为终点的次数。
这样最多只用算200000*4次,不会超时。
泪奔的我为了减少代码量直接忽略了0点,* * * * * *某快递!!!
A:这是一个签到题
总时间限制: 1000ms 内存限制: 65535kB 描述 计算A+B+C的和。 输入 多组测试数据。 输入A,B,C,保证是小于100的正整数。 输出 对于每组数据输出A,B,C的和。 样例输入 1 2 3 3 4 5 样例输出 6 12
这是一道水题,代码很简单。
#include<stdio.h> #include"string.h" int main() { int a,b,c; while(scanf("%d %d %d",&a,&b,&c)!=EOF) { int ans=a+b+c; printf("%d\n",ans); } return 0; }
B:A+B+C+D+….
总时间限制: 1000ms 内存限制: 65535kB 描述 给你一个数组,你要做的就是计算|a1|+|a2|+....+|an|。 输入 先输入一个T。表示有T组测试数据 每组测试数据先输入一个n,n<100.表示数组的个数。接下来是n个整数ai(-10^5≤ai≤10^5) 输出 输出n个数的绝对值之和 样例输入 2 3 1 1 1 3 -1 -1 -1 样例输出 3 3
绝对值可以使用if大于0进行判定,尽量少使用math.h的东西。
#include<stdio.h> int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); int ans=0; while(n--) { int a; scanf("%d",&a); if(a>0) ans=ans+a; else ans=ans-a; } printf("%d\n",ans); } return 0; }
C:导弹拦截之终结版
总时间限制: 1000ms 内存限制: 65535kB 描述 经过100 年的韬光养晦,某国研发出了一种用于太空战争的导弹拦截系统,凡是与它的距离不超过其工作半径的导弹都能够被它成功拦截。而且没有缺陷。 某天,雷达捕捉到外星人的导弹来袭。由于该系统尚处于试验阶段,所以只有一套系统投入工作。请计算可以拦截下的导弹个数。 输入 多组测试数据; 对于每组数据共有两行: 第一行一个n(0≤n≤1000),表示导弹个数,一个m,表示工作半径(0≤m≤30000); 第二行表示每颗导弹与拦截系统的距离Li(0≤Li≤30000),以空格隔开 。 输出 每组数据一行,输出可以拦截下的导弹个数; 样例输入 8 200 389 207 155 300 299 170 158 65 样例输出 4
这道题先输入拦截高度,对于每颗导弹的高度后面已经不需要了,所以这里连数组都不需要,直接一个扫过去统计就行了。
#include<stdio.h> int main() { int n,m; while(scanf("%d %d",&n,&m)!=EOF) { int ans=0; int a; while(n--) { scanf("%d",&a); if(a<=m) ans++; } printf("%d\n",ans); } return 0; }
D:你是第一吗
总时间限制: 1000ms 内存限制: 65535kB 描述 西科大的计科学院的同学是一群热爱学习的同学,在国庆节就开始提前学习C语言。 在一次C语言测试中,我们得到了所有同学的成绩。我们发现大家都很厉害,为什么呢?因为有很多同学的分都很高,现在我想知道有多少个并列第一名呢? 注意:当且仅当分一样且都是最高分才为并列第一名 输入 多组测试数据; 对于每组数据: 输入包含两行; 第一行包含一个正整数n(1 <= n <= 20000),表示第二行序列中数字的个数; 第二行包含n个整数,整数之间以一个空格分开。每个整数大于等于0、小于等于100。 输出 每组数据输出只有一行,输出并列第一名的个数。 样例输入 10 100 75 93 72 75 85 100 92 85 100 样例输出 3 提示 这个题目就是问所有分数中最高分有几个。如下样例数据最高分为100分,且有3个,则输出3.
这个题可以用模拟,就是用两个数记录,一个是记录当前最大值,扫到后一个比他小就跳过,相同就用另一个变量count+1,比他大就替换最大值,并且count重新为0就行了。代码这里就没写了。
另一种方法是用排序,c语言课本上有冒泡排序的代码,这里有一种更方便的快速的排序方法,是c++STL里面的东西,可以直接使用。
#include"algorithm"引入这个头文件,用法就是
sort(a,a+n);这样就可以从小到大排序。其中a是排序的起点,a+n是排序的终点,这个函数同样适用于数组中的一部分。
这里要求从大到小排序,所以手写自定义比较函数cmp, 自定义排序规则。这个同样可用于结构体排序。
#include"string.h"
memset(a,0,sizeof(a));是对数组进行内存按位0,等价于for循环遍历数组让每个值都等于0。
顺便吐槽某出题人的错误数据,吓得我以为一段时间没摸代码,排序都不会了。
#include<stdio.h> #include"algorithm" #include"string.h" int cmp(int a,int b) { return a>b; } using namespace std; int main() { int n; int a[20005]; while(scanf("%d",&n)!=EOF) { memset(a,0,sizeof(a)); for(int i=0; i<n; i++) { scanf("%d",&a[i]); } sort(a,a+n,cmp); int ans=1; int maxn=a[0]; for(int i=1;i<n;i++) { if(a[i]==maxn) ans++; else break; } printf("%d\n",ans); } return 0; }
E:紧急措施
总时间限制: 1000ms 内存限制: 65535kB 描述 近日,一些热门网站遭受黑客入侵,这些网站的账号、密码及email的数据惨遭泄露。你此时拿到了那份泄露的数据,希望尽快将自己的密码更改。策略如下:小写和大写交换,非字母字符保持不变。 输入 多组测试数据; 对于每组数据: 一行一串字符,不包括空格(长度<=100)。 输出 每组数据一行,输出更改后的密码。 样例输入 5iKitty Feb.29$ 样例输出 5IkITTY fEB.29$ 提示 参考ASCII对照表。
这个题并没有什么坑的地方,直接scanf %s就行了。
#include<stdio.h> #include"string.h" #include"iostream" using namespace std; int main() { char a[105]; while(cin>>a) { for(int i=0;a[i];i++) { if(a[i]>=65&&a[i]<=90) { a[i]=a[i]+32; } else if(a[i]>=97&&a[i]<=122) { a[i]=a[i]-32; } } cout<<a<<endl; } return 0; }
F:我们的征途是星辰大海
总时间限制: 1000ms 内存限制: 65535kB 描述 在很多年后,人类终于研究出来一个自动探索宇宙的飞船-----征途号。 现在征途号遇到了陨石群。 为了方便分析,征途号上的智能系统对当前空间建立三维直角坐标系,当前征途号位于坐标(0,0,0),现在征途号发射一颗炮弹沿直线击打目标点T(x,y,z),现在雷达系统给出n个陨石的坐标。那么请你设计程序来计算这个炮弹在飞行过程中会击落多少个陨石? 输入 多组测试数据; 对于每组数据: 第一行包括三个数x,y,z,表示目标点; 第二行一个n(0≤n≤1000); 接下来n行,每行三个数,代表每个陨石的坐标,保证不重复出现; 对于每个坐标,保证都为int范围内的整数; 保证原点和目标点没有陨石。 输出 每组数据输出只有一行,输出应该击毁的陨石数目。 样例输入 10 10 10 5 5 5 5 5 5 4 1 1 1 7 9 8 -1 -1 -1 样例输出 2 提示 注意除法会产生精度误差。改成乘法判断 这里主要考虑是否在一条直线上,并且陨石在飞船和目标之间。
这个题我觉得坑的地方是在于目标点坐标可以为负,错了4遍的我还在已经把某快递吐槽了千万遍了。
#include<stdio.h> #include"string.h" #include"iostream" using namespace std; int main() { int x,y,z; while(scanf("%d %d %d",&x,&y,&z)!=EOF) { int ans=0; int n; scanf("%d",&n); while(n--) { int a,b,c; scanf("%d %d %d",&a,&b,&c); //暴力枚举6种坐标点不在定义域的情况 if(x>0&&(a<0||a>x)) continue; if(x<0&&(a>0||a<x)) continue; if(y>0&&(b<0||b>y)) continue; if(y<0&&(b>0||b<y)) continue; if(z>0&&(c<0||c>z)) continue; if(z<0&&(c>0||c<z)) continue; //就是这里被快递坑了 //if((a>=0)&&(a<=x)&&(b>=0)&&(b<=y)&&(c>=0)&&(c<=z)) //前面三个判断是用数学上的向量平行,高数会讲,所以学好高数很重要。 //!加上一个非0变量等于0,!0=1,这里用来判断是否与原点和终点重合。 if((a*y==b*x)&&(b*z==c*y)&&(a*z==c*x)&&((!a+!b+!c)!=3)&&((!(x-a)+!(y-b)+!(z-c))!=3)) { ans++; } } printf("%d\n",ans); } return 0; }
G:巧克力
总时间限制: 1000ms 内存限制: 65535kB 描述 罗海川学长和孙其灵学长都喜欢吃巧克力,巧克力真的很好吃。我们团队的队员也很喜欢吃,但是由于人数比较多,而他们又不想再去买巧克力,所以两位学长决定将一个N*M*K的长方体的巧克力分解成1*1*1的正方体小块,这样就可以分给更多的人了。但是两个学长分解巧克力的方法不同,罗海川学长由于没有工具,所以只能用手掰,可以将一块掰成两块。而孙其灵学长事先有准备,有一把足够长的刀,所以孙其灵学长用刀切,可以将一些切成两半。现在你能告诉我们罗海川学长和孙其灵学长将巧克力都分解成1*1*1的正方体小块最少需要多少步吗? 输入 输入包括多组测试数据。 输入三个数 N,M,K(1 <=N,M,K <=2000)在一行,用空格隔开。 表示巧克力的大小N*M*K。 输出 分别输出罗海川学长和孙其灵学长分解巧克力所用的最小步数。 样例输入 1 1 3 2 2 2 样例输出 2 2 7 3 提示 数据较大,请使用long long int,数据格式为%lld 多组输入可以用while(scanf()!=EOF)的格式
typedef是用来定义别名,减少代码量,c语言书上会讲。
1<< i是求1*2^i,尽量少用log函数,至于原因以后吃亏了就知道了。
这个题目要求最少刀数,就像切豆腐一样,1*4的平面豆腐可以切成两个1*2的,再把这两个1*2的叠起来再切一刀,所以只需要求二分就行了,别问我怎么这么坑的切法,问快递去,我以为那个豆腐放在那里不能叠呢。
#include<stdio.h> #include"algorithm" #include"string.h" #include"iostream" using namespace std; typedef long long int lint; int main() { lint x,y,z; while(scanf("%lld %lld %lld",&x,&y,&z)!=EOF) { lint a=x*y*z-1; int i; lint b=0; i=0; while((1<<i)<x) i++; b=b+i; i=0; while((1<<i)<y) i++; b=b+i; i=0; while((1<<i)<z) i++; printf("%lld %lld\n",a,b); } return 0; }
H:刷墙
总时间限制: 1000ms 内存限制: 65535kB 描述 在一面很长的墙壁上,工人们用不同的油漆去刷墙,然而可能有些地方刷过以后觉得不好看,他们会重新刷一下。有些部分因为重复刷了很多次覆盖了很多层油漆,Mzx0821很好奇那些地方被刷过多少种颜色的油漆。 输入 若干行输入,每行两个数字B[i],E[i](0<=B[i]<=E[i]<=200000)表示这次刷的墙壁是哪一段(假设每次刷的时候油漆颜色都和之前的不同),以0 0结束 又若干行输入,每行两个数字begin[i],end[i](0<=begin[i]<=end[i]<=200000)表示Mzx0821询问的段,以0 0结束 输出 对于每个Mzx0821的询问输出(end[i]-begin[i]+1)行,表示对应询问段的每个点被多少种颜色的油漆覆盖过。 样例输入 1 20 5 10 10 20 0 0 4 6 10 11 0 0 样例输出 1 2 2 3 2
很多同学这道题超时吧?可以算一下,如果我每次从第一个刷到第20000个,再刷这么多次(这就是题目给的最大数据量,但是一般后台都会出这么死变态的数据),那么就要算10^10次,给的时间是1s,能算10^8次,所以TLE的摸头不哭。
这里比较套模版的是用线段树做,那个他复杂,这里给一个简单的代码。
我用三个数组分别存在每次刷墙的起点终点和次数。那么每次就等于上次刷的次数加这个点作为起点的次数和减去这个点作为终点的次数。
这样最多只用算200000*4次,不会超时。
泪奔的我为了减少代码量直接忽略了0点,* * * * * *某快递!!!
#include"stdio.h" #include"string.h" const int maxn=200005; int a[maxn]; int b[maxn]; int c[maxn]; int main() { //freopen("1.txt","r",stdin); memset(a,0,sizeof(a)); //+ memset(b,0,sizeof(b)); //- memset(c,0,sizeof(c)); //value int x,y; while(scanf("%d %d",&x,&y)!=EOF) { if(x==0&&y==0) break; a[x]++; b[y]++; } int temp=0; for(int i=0; i<maxn; i++) { c[i]=temp+a[i]; temp=c[i]-b[i]; } while(scanf("%d %d",&x,&y)!=EOF) { if(x==0&&y==0) break; for(int i=x; i<=y; i++) { printf("%d\n",c[i]); } } return 0; }
快说我萌!!!!!
相关文章推荐
- POJ 1741 Tree 树 点分治
- JavaScript中的运算符
- imageNamed 与 imageWithContentsOfFile差额
- C# 中栈和队的区别
- andriod开发点滴(在listView上添加了一个checkbox后,点击list无响应)
- 生命游戏
- Android 学习经典教材(Eclips)
- linux常用命令总结
- centos在设置时区
- 多种数据输入
- 【软考】设计模式(上午题)
- unity官方demo学习之Stealth(二十一)敌人动画设置类
- android eclipse ndk使用记录
- [PAT]1098. Insertion or Heap Sort (25)
- leetcode - Sort Colors
- centos 安装smplayer
- 工具类4
- Visual Studio2015切换开发环境方法
- Android Studio配置 AndroidAnnotations——Hi_博客 Android App 开发笔记
- 安装"MySQLdb"一波三折.