消除类游戏
描述
问题描述
消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有n行m列的游戏棋盘上进行,棋盘的每一行每一列的方格上放着一个有颜色的棋子,当一行或一列上有连续三个或更多的相同颜色的棋子时,这些棋子都被消除。当有多处可以被消除时,这些地方的棋子将同时被消除。
现在给你一个n行m列的棋盘,棋盘中的每一个方格上有一个棋子,请给出经过一次消除后的棋盘。
请注意:一个棋子可能在某一行和某一列同时被消除。
输入格式
输入的第一行包含两个整数n, m,用空格分隔,分别表示棋盘的行数和列数。
接下来n行,每行m个整数,用空格分隔,分别表示每一个方格中的棋子的颜色。颜色使用1至9编号。
输出格式
输出n行,每行m个整数,相邻的整数之间使用一个空格分隔,表示经过一次消除后的棋盘。如果一个方格中的棋子被消除,则对应的方格输出0,否则输出棋子的颜色编号。
样例输入
4 5
2 2 3 1 2
3 4 5 1 4
2 3 2 1 3
2 2 2 4 4
样例输出
2 2 3 0 2
3 4 5 0 4
2 3 2 0 3
0 0 0 4 4
样例说明
棋盘中第4列的1和第4行的2可以被消除,其他的方格中的棋子均保留。
样例输入
4 5
2 2 3 1 2
3 1 1 1 1
2 3 2 1 3
2 2 3 3 3
样例输出
2 2 3 0 2
3 0 0 0 0
2 3 2 0 3
2 2 0 0 0
样例说明
棋盘中所有的1以及最后一行的3可以被同时消除,其他的方格中的棋子均保留。
评测用例规模与约定
所有的评测用例满足:1 ≤ n, m ≤ 30。
分析
挺迷的,一开始总是30分,不知道改了哪里,突然就过了……
听上去很麻烦,但是CCF的题,只要数据量不大,那完全就可以按照最符合直觉的思路来
就遍历就好了,每次查看是不是有三个相同。什么?三个以上?只要迭代是加一的,三个三个的总能全部找到的
只需要用另一个数组来专门负责标记就好了,这样也不怕重复标记
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
int chess[32][32];
int ans[32][32];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i = 0;i<n;i++)
for(int j=0;j<m;j++)
{
scanf("%d",&chess[i][j]);
ans[i][j] = chess[i][j];
}
int i=0 ,j = 0;
for( i =0; i<n;i++)
{
for(j = 0;j<m;j++)
{
if(j+1<m && j+2<m)
{
if(chess[i][j]==chess[i][j+1] && chess[i][j+2]==chess[i][j])
{
ans[i][j]=0;
ans[i][j+1]=0;
ans[i][j+2] = 0;
}
}
if(i+1<n && i+2 <n)
{
if(chess[i][j]==chess[i+1][j]&& chess[i+2][j]==chess[i][j])
{
ans[i][j]=0;
ans[i+1][j]=0;
ans[i+2][j]=0;
}
}
}
}
for(int i = 0;i<n;i++)
{
for(int j = 0;j<m;j++)
{
printf("%d ",ans[i][j]);
}
printf("\n");
}
}
}
日期计算
描述
问题描述
给定一个年份y和一个整数d,问这一年的第d天是几月几日?
注意闰年的2月有29天。满足下面条件之一的是闰年:
1) 年份是4的整数倍,而且不是100的整数倍;
2) 年份是400的整数倍。
输入格式
输入的第一行包含一个整数y,表示年份,年份在1900到2015之间(包含1900和2015)。
输入的第二行包含一个整数d,d在1至365之间。
输出格式
输出两行,每行一个整数,分别表示答案的月份和日期。
样例输入
2015
80
样例输出
3
21
样例输入
2000
40
样例输出
2
9
分析
用了《王道机试指南》中的思路,一天天增加日期。对于闰年的判断基于二维数组,可以说是很机智了
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int isPrime(int y)
{
if(y%400==0 || (y%4==0&&y%100!=0))return 1;
return 0;
}
int months[13][2]={
0,0,
31,31,
28,29,
31,31,
30,30,
31,31,
30,30,
31,31,
31,31,
30,30,
31,31,
30,30,
31,31
};
struct date{
int y,m,d;
void addDay(){
d ++;
if(d>months[m][isPrime(y)])
{
d = 1; m ++;
if(m>12)
{
m = 1; d = 1;y ++;
}
}
}
};
int main()
{
int y,d;
while(~scanf("%d%d",&y,&d))
{
date newday ;
newday.y = y;
newday.m = 1;
newday.d = 1;
int i = 1;
while(i<d)
{
newday.addDay();
i++;
}
printf("%d\n%d\n",newday.m,newday.d);
}
}
图形旋转
描述
问题描述
旋转是图像处理的基本操作,在这个问题中,你需要将一个图像逆时针旋转90度。
计算机中的图像表示可以用一个矩阵来表示,为了旋转一个图像,只需要将对应的矩阵旋转即可。
输入格式
输入的第一行包含两个整数n, m,分别表示图像矩阵的行数和列数。
接下来n行每行包含m个整数,表示输入的图像。
输出格式
输出m行,每行包含n个整数,表示原始矩阵逆时针旋转90度后的矩阵。
样例输入
2 3
1 5 3
3 2 4
样例输出
3 4
5 2
1 3
评测用例规模与约定
1 ≤ n, m ≤ 1,000,矩阵中的数都是不超过1000的非负整数。
分析
after[i][j] = ori[j][m-i+1];
思路就是按照翻转后的列来往里面填充,就比较容易能找到规律了
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int ori[1005][1005];
int after[1005][1005];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i = 1;i<=n;i++)
for(int j = 1;j<=m;j++)
scanf("%d",&ori[i][j]);
for(int i = 1;i<=m;i++)
for(int j =1;j<=n;j++)
{
after[i][j] = ori[j][m-i+1];
}
for(int i = 1;i<=m;i++)
{
for(int j = 1;j<=n;j++)
{printf("%d ",after[i][j]);
}
printf("\n");
}
}
}
数字排序
描述
问题描述
给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。
输入格式
输入的第一行包含一个整数n,表示给定数字的个数。
第二行包含n个整数,相邻的整数之间用一个空格分隔,表示所给定的整数。
输出格式
输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数。按出现次数递减的顺序输出。如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。
样例输入
12
5 2 3 3 1 3 4 2 5 2 3 5
样例输出
3 4
2 3
5 3
1 1
4 1
评测用例规模与约定
1 ≤ n ≤ 1000,给出的数都是不超过1000的非负整数。
分析
先用map计数每个数字出现的次数。但是map默认是按key从小到大排序的,不可以,所以又将结果存入到struct中对struct按照规则排序得到结果;
看到网上的另一种思路是两层遍历,找序号最小又最大的
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
map<int,int>cnt;
struct PAIR{
int key,value;
}p[1005];
bool cmp(PAIR &a,PAIR &b)
{
if(a.value!=b.value)return a.value>b.value;
else return a.key<b.key;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
int x;
cnt.clear();
for(int i = 0;i<n;i++)
{
cin>>x;
cnt[x]++;
}
map<int,int>::iterator it;
int pos = 0;
for(it = cnt.begin();it!=cnt.end();it++)
{
p[pos].key = it->first;
p[pos].value = it->second;
pos++;
}
sort(p,p+pos,cmp);
for(int i =0;i<pos;i++)
{
printf("%d %d\n",p[i].key,p[i].value);
}
}
}