比赛前老师说不让拿书,都是我们没见过的题,看到题后我笑了,基本上都是似曾相识的。。
1. 把手放在键盘上时,稍不注意就会往右错一位,这样, Q 就编程变成了 W, J 就变成了 K 等, 电
脑键盘如图所示, (错位字符串内容限定在红线包含区域,且不包含上档键)
编程实现:输入一个错位后的字符串,输出本来想打的句子。
如错位字符串为: OS,GOMR YPSFU/,输出: I AM FINE TODAY
图就不给了,本题为小白书(算法竞赛入门经典)69页的WERTYU。
解决:
1.查找;
2.输出。
代码:
#include<stdio.h>
char *s = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
int main()
{
int i, c;
while((c = getchar()) != EOF){
for(i = 1; s[i] && s[i] != c; i++);
if(s[i]) putchar(s[i - 1]);
else putchar(c);
}
return 0;
}
2.开灯问题: 有 n 盏灯, 编号为 1~n, 第一个人把所有灯打开, 第 2 个人按下所有是 2 的倍数的开
关, 第 3 个人按下所有编号为 3 的倍数的开关(其中关着的灯将被打开, 打开的灯将被关闭), 以此
类推,一共有 k 个人,问最后哪些灯开着?输入 n 和 k,输出开着灯的编号。(k<=n<=100)
如: n 和 k 分别为 7 和 3,则输出为 1 5 6 7
此题为南阳理工OJ第77题,模拟一下就行了
代码:
#include<stdio.h>
#include<string.h>
int a[1010];
int main()
{
int n,k,s,i,j;
memset(a,1,sizeof(a));
scanf("%d%d",&n,&k);
for(i = 2; i <= n; i++)
for(j = 2; j <= k; j++)
if(i % j == 0)
a[i] =! a[i];
for(i = 1; i <= n; i++)
if(a[i])
printf("%d ",i);
printf("\n");
return 0;
}
3.甲乙丙丁同时开始放鞭炮, 甲每隔t1 秒放一次, 乙每隔 t2 秒放一次, 丙每隔 t3 秒放一次, 丁每隔
t4 秒放一次,每人各放 n 次,求共听到多少次鞭炮声(当几个鞭炮同时炸响,只算一次响声,第一
次响声是在 0 秒)? 如: t1=7,t2=5,t3=6,t4=4,n=10,则结果为 28。
这题当时一看懵了一下,类似第二题,同样模拟
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[1010];
int main()
{
int n, t1, t2, t3, t4;
scanf("%d%d%d%d%d", &t1, &t2, &t3, &t4, &n);
for(int i = 0; i < n; i++){
a[i * t1] = 1;
a[i * t2] = 1;
a[i * t3] = 1;
a[i * t4] = 1;
}
int s = 0;
int Max = max(max(t1, t2), max(t3, t4));
for(int i = 0; i <= (n - 1) * Max; i++)
if(a[i])
s++;
printf("%d\n", s);
return 0;
}
题中给的数据运行结果为29,比赛后也有很多人说是29,这个也许是周老师。。。
4.输入正整数n(n<30),把整数1,2,3,
……,n组成一个环,使得相邻两个整数之和均为素数,输出时
从整数
1 开始逆时针排列。
如输入
n 为
6,则输出:
1 4 3 2 5 6;
n 为
8 时,输出为
1 2 3 8 5 6 7 4
素数环,小白书126页,南阳理工OJ488题,当时这题卡了很长时间,回溯算法掌握的还不是太牢。再敲一遍代码,加深印象吧!
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int isp[100], A[20], vis[20];
int n, ok;
int is_prime(int n)
{
for(int i = 2; i * i <= n; i++) if(n % i == 0) return 0;
return 1;
}
void dfs(int cur)
{
if(ok) return; //只输出一组答案
if(cur == n && isp[A[0] + A[n - 1]]){
for(int i = 0; i < n; i++) printf("%d ", A[i]); //打印方案
printf("\n");
ok = 1;
}
else for(int i = 2; i <= n; i++) //尝试放置每个数i
if(!vis[i] && isp[i + A[cur - 1]]){ //如果i没用过,且与前一个数之和为素数
A[cur] = i;
vis[i] = 1; //记为已经使用
dfs(cur + 1); //判断下一个
vis[i] = 0; //清除标记
}
}
int main()
{
scanf("%d", &n);
for(int i = 2; i <= n * 2; i++) isp[i] = is_prime(i); //生成素数表,加快后续判断
A[0] = 1; //第一个数为 1
vis[1] = 1;
dfs(1);
return 0;
}
5.有10 箱产品每箱有 1000 件,正品每件 100 克。其中只有一箱是次品,次品每件比正品轻 10 克,
问能否用秤只称一次,就找出哪一箱是次品。
这题当时没做出来,一个思维题,比赛结束后听学长一讲就清楚了。
解法:
将十箱产品标号为1-10,取产品,标号为1的那箱取1件,标号为2的那箱取2件。。。。标号为几就取几件。
称一下所取物品的总质量,如果全为正品,则总质量为5500,
如果1号箱是次品,则总质量为5490,如果2号箱是次品,则为5480,
于是,设最后的总质量为sum,第x箱为次品,则 x = (5500 - sum) / 10.
最后讲题的时候学长告诉我们这是一种解题方法,数字信息化,感觉好强大!
以后的路还很长,不管如何都要坚持下去。
路漫漫其修远兮,吾将上下而求索。