记录洛谷刷题QAQ
一、手机
题目描述
一般的手机的键盘是这样的:
要按出英文字母就必须要按数字键多下。例如要按出 x
就得按 9 两下,第一下会出 w
,而第二下会把 w
变成 x
。0 键按一下会出一个空格。
你的任务是读取若干句只包含英文小写字母和空格的句子,求出要在手机上打出这个句子至少需要按多少下键盘。
输入格式
一行句子,只包含英文小写字母和空格,且不超过 200 个字符。
输出格式
一行一个整数,表示按键盘的总次数。
样例 #1
样例输入 #1
i have a dream
样例输出 #1
23
提示
NOI 导刊 2010 普及(10)
代码如下:
#include <stdio.h>
#include <stdlib.h>
#define M 10001
#include <string.h>
int main(int argc, char *argv[]) {
char NUM[201];
gets(NUM);
int sum = 0;
int len = strlen(NUM);
for(int i = 0;i < len;i++){
if(NUM[i] == 'b'||NUM[i] == 'e'||NUM[i] == 'h'||NUM[i] == 'k'||NUM[i] == 'n'||NUM[i] == 'q'||NUM[i] == 'u'||NUM[i] == 'x')
sum =sum + 2;
else if(NUM[i] == 'a'||NUM[i] == 'd'||NUM[i] == 'g'||NUM[i] == 'j'||NUM[i] == 'm'||NUM[i] == 'p'||NUM[i] == 't'||NUM[i] == 'w'||NUM[i] == ' ')
sum = sum + 1;
else if(NUM[i] == 'c'||NUM[i] == 'f'||NUM[i] == 'i'||NUM[i] == 'l'||NUM[i] == 'o'||NUM[i] == 'r'||NUM[i] == 'v'||NUM[i] == 'y')
sum =sum + 3;
else if(NUM[i] == 's'||NUM[i] == 'z')
sum = sum + 4;
}
printf("%d\n",sum);
return 0;
}
二、【Mc生存】插火把
题目背景
初一党应该都知道…
题目描述
话说有一天 linyorson 在“我的世界”开了一个 n × n n \times n n×n 的方阵,现在他有 m m m 个火把和 k k k 个萤石,分别放在 ( x 1 , y 1 ) ∼ ( x m , y m ) (x_1, y_1) \sim (x_m, y_m) (x1,y1)∼(xm,ym) 和 ( o 1 , p 1 ) ∼ ( o k , p k ) (o_1, p_1) \sim (o_k, p_k) (o1,p1)∼(ok,pk) 的位置,没有光或没放东西的地方会生成怪物。请问在这个方阵中有几个点会生成怪物?
P.S. 火把的照亮范围是:
|暗|暗| 光 |暗|暗|
|暗|光| 光 |光|暗|
|光|光|火把|光|光|
|暗|光| 光 |光|暗|
|暗|暗| 光 |暗|暗|
萤石:
|光|光| 光 |光|光|
|光|光| 光 |光|光|
|光|光|萤石|光|光|
|光|光| 光 |光|光|
|光|光| 光 |光|光|
输入格式
输入共
m
+
k
+
1
m + k + 1
m+k+1 行。
第一行为
n
,
m
,
k
n, m, k
n,m,k。
第
2
2
2 到第
m
+
1
m + 1
m+1 行分别是火把的位置
x
i
,
y
i
x_i, y_i
xi,yi。
第
m
+
2
m + 2
m+2 到第
m
+
k
+
1
m + k + 1
m+k+1 行分别是萤石的位置
o
i
,
p
i
o_i, p_i
oi,pi。
注:可能没有萤石,但一定有火把。
输出格式
有几个点会生出怪物。
样例 #1
样例输入 #1
5 1 0
3 3
样例输出 #1
12
提示
数据保证, 1 ≤ n ≤ 100 1 \le n \le 100 1≤n≤100, 1 ≤ m + k ≤ 25 1 \leq m+k \leq 25 1≤m+k≤25, 1 ≤ m ≤ 25 1 \leq m \leq 25 1≤m≤25, 0 ≤ k ≤ 5 0 \leq k \leq 5 0≤k≤5。
代码如下:
#include<stdio.h>
int n,m,k,x,y,i,j,u,v,ans;//n,m,k(题目),x,y(临时坐标),i,j,u,v(循环变量),ans(答案)。
int main(){
int ma[1000][1000];//自己试了几次,数据只有这么大……
scanf("%d %d %d", &n, &m, &k);
for(i=1;i<=m;i++){//火把
scanf("%d %d", &x, &y);
ma[x-2][y]=ma[x-1][y+1]=ma[x-1][y]=ma[x-1][y-1]=ma[x][y+2]=ma[x][y+1]=ma[x][y]=ma[x][y-1]=ma[x][y-2]=ma[x+1][y+1]=ma[x+1][y]=ma[x+1][y-1]=ma[x+2][y]=1;//要标记有光的。(慢慢打,有点麻烦。)
}
for(i=1;i<=k;i++){//萤石
scanf("%d %d", &x, &y);
for(u=-2;u<=2;u++)
for(v=-2;v<=2;v++)
ma[x+u][y+v]=1;//萤石用循环标记,代码就短一些。
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(ma[i][j]==0)
ans++;
printf("%d", ans);
return 0;
}
三、轰炸III
题目背景
一个大小为 n × m n\times m n×m 的城市遭到了 x x x 次轰炸,每次都炸了一个每条边都与边界平行的矩形。
题目描述
在轰炸后,有 y y y 个关键点,指挥官想知道,它们有没有受到过轰炸,如果有,被炸了几次,最后一次是第几轮。
输入格式
第一行共四个整数,分别为 n , m , x , y n,m,x,y n,m,x,y。
接下来 x x x 行,每行四个整数 x 1 , y 1 , x 2 , y 2 x_1,y_1,x_2,y_2 x1,y1,x2,y2,表示被轰炸的矩形的左上角坐标和右下角坐标(比如 1 , 3 , 7 , 10 1,3,7,10 1,3,7,10 就表示被轰炸的地方是从 ( 1 , 3 ) (1,3) (1,3) 到 ( 7 , 10 ) (7,10) (7,10) 的矩形)。
接下来 y y y 行,每行两个整数,表示这个关键点的坐标。
输出格式
输出共
y
y
y 行,每行第一个字符为 Y
或 N
,表示是否被轰炸;若为 Y
,在一个空格后为两个整数,表示被炸了几次和最后一次是第几轮。
样例 #1
样例输入 #1
10 10 2 3
1 1 5 5
5 5 10 10
3 2
5 5
7 1
样例输出 #1
Y 1 1
Y 2 2
N
提示
对于 100 % 100\% 100% 数据,满足 1 ≤ n , m ≤ 100 1\le n,m\le 100 1≤n,m≤100。
代码如下:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int N, M, x, y;
while(scanf("%d%d%d%d",&N,&M,&x,&y)!=EOF){
int x1[x], y1[x], x2[x], y2[x];
for(int i = 1;i <= x;i++){
scanf("%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i]);
}
int X[y], Y[y];
for(int i = 0;i < y;i++){
scanf("%d%d",&X[i],&Y[i]);
}
for(int j = 0;j < y;j++){
int point = 0, sum = 0;
for(int i = 1;i <= x;i++){
if(X[j] >= x1[i] && X[j] <= x2[i] && Y[j] >= y1[i] && Y[j] <= y2[i]){
point = i;
sum++;
}
}
if(point != 0){
printf("Y");
printf(" %d %d\n",sum,point);
}
else if(point == 0){
printf("N\n");
}
}
}
return 0;
}
四、三子棋I
题目描述
小a和uim喜欢互相切磋三子棋。三子棋大家都玩过是吗?就是在九宫格里面OOXX(别想歪了),谁连成3个就赢了。
由于小a比较愚蠢,uim总是让他先。
我们用9个数字表示棋盘位置:
123
456
789
所有的棋谱都是已经结束的棋局,要么一方获胜,要么平局。
今天,他们下了一下午的棋,小a为了提高技术,录下了很多棋谱。他想知道,一盘棋结束时,到底是谁赢。
输入格式
一行,一串数字,表示落子的地点。小a总是先下
输出格式
一行,如果小a赢,输出“xiaoa wins.”。如果uim赢,输出“uim wins.”。如果平局,输出“drew.”
样例 #1
样例输入 #1
5237649
样例输出 #1
xiaoa wins.
样例 #2
样例输入 #2
539128647
样例输出 #2
drew.
代码如下:
#include<stdio.h>
#include<string.h>
char s[10];
int main()
{
scanf("%s", s);
int len = strlen(s);
if(len < 9)
{
if(len % 2 == 1) printf("xiaoa wins.");
else if(len % 2 == 0) printf("uim wins.");
}
else if(len == 9)
{
if(s[0] == 49 && s[1] == 50) printf("xiaoa wins.");
else printf("drew.");
}
return 0;
}
五、好朋友
题目背景
小可可和所有其他同学的手腕上都戴有一个射频识别序列号码牌,这样老师就可以方便的计算出他们的人数。很多同学都有一个“好朋友” 。如果 A A A 的序列号的约数之和恰好等于 B B B 的序列号,那么 A A A 的好朋友就是 B B B。在这里,一个数的约数不包括这个数本身。因为一些同学的号码约数和大于其他任何同学的号码,所以这些同学没有好朋友。一些同学有一个“非常好友” 。当两个同学互为“好朋友”时,他们就是一对“非常好友” 。注意在这道题中,忽略那些自己是自己的“非常好友”的情况。
题目描述
给定一个序列号 s s s,找出序列号不小于 s s s 的第一对“非常好友” 。
输入格式
只有一行一个整数 s s s,即给定的序列号下界。
输出格式
输出一行两个用空格隔开的整数 a a a 和 b b b。
a a a 表示第一个序列号不小于 s s s 的有“非常好友”的同学, b b b 是 a a a 的“非常好友” 。(注:允许 b < s b<s b<s)
样例 #1
样例输入 #1
206
样例输出 #1
220 284
提示
数据规模与约定
- 对于 100 % 100\% 100% 的数据,保证 6 ≤ s ≤ 1.8 × 1 0 4 6\le s\le1.8\times10^4 6≤s≤1.8×104。
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
int a(int r){//计算约数和的函数
long long s=0;//约数和的累加器
for(int i=1;i<r;i++){
if(r%i==0)s+=i;//累加约数
}
return s;//返回约数和
}
int main()
{
int n,t,now;//n是开始序列号,t是当前序列号,now是序列号为t的同学的好友的序列号
scanf("%d",&n);//输入开始序列号
t=n;//当前序列号即开始序列号
while(1){
//循环
now=a(t);//序列号为t的同学的好友的序列号赋值
if(a(now)==t&&now!=t){//判断是否为“非常好友”,同时排除掉自己是自己的“非常好友”的情况。
printf("%d %d",t,now);//输出时因为会先轮小号,所以now必大于t,可直接输出
return 0;//结束
}
t++;//当前序列号累加
}
}