2021-2013CSP前两题记录
- 202104-1灰度直方图
- 202104-2 邻域均值
- 202012-1期末预测之安全指数
- 202012-2 期末预测之最佳阈值
- 202009-1 称检测点查询
- 202009-2 风险人群筛查
- 202006-1 线性分类器
- 202006-2 稀疏向量
- 201912-1 报数
- 201912-2 回收站选址
- 201909-1 小明种苹果
- 201909-2 小明种苹果(续)
- 201903-1 小中大
- 201903-2 二十四点
- 201812-1 小明上学
- 201812-2小明放学
- 201809-1 卖菜
- 201809-2 买菜
- 201803-1 跳一跳
- 201803-2 碰撞的小球
- 201712-1 最小差值
- 201712-2 游戏
- 201709-1打酱油
- 201709-2 公共钥匙盒
- 201703-1 分蛋糕
- 201703-2 学生排队
- 201612-1 中间数
- 201612-2 工资计算
- 201609-1 最大波动
- 201609-2 火车购票
- 201604-1折点计数
- 201604-2 俄罗斯方块
- 201512-1 数位之和
- 201512-2 消除类游戏
- 201509-1 数列分段
- 201509-2日期处理
- 201503-1图像旋转
- 201503-2 数字排序
- 201412-1门禁系统
- 201412-2 Z字形扫描
- 201409-1 相邻数对
- 201409-2画图
- 201403-1相反数
- 201403-2 窗口
- 201312-1 出现次数最多的数
- 201312-2 ISBN号码
- 撒花花*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。
202104-1灰度直方图
样例输入:
4 4 16
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
样例输出:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
样例输入:
7 11 8
0 7 0 0 0 7 0 0 7 7 0
7 0 7 0 7 0 7 0 7 0 7
7 0 0 0 7 0 0 0 7 0 7
7 0 0 0 0 7 0 0 7 7 0
7 0 0 0 0 0 7 0 7 0 0
7 0 7 0 7 0 7 0 7 0 0
0 7 0 0 0 7 0 0 7 0 0
样例输出:
48 0 0 0 0 0 0 29
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int main() {
int n, m, L;
scanf("%d %d %d",&n,&m,&L);
int i, j;
int temp;
int a[300];
for (i = 0; i < 300; i++)
{
a[i] = 0;
}
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
scanf("%d",&temp);
a[temp]++;
}
}
for (i = 0; i < L; i++)
printf("%d ",a[i] );
return 0;
}
202104-2 邻域均值
样例输入:
4 16 1 6
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
样例输出:
7
样例输入:
11 8 2 2
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 7 0 0 0 7 0 0 7 7 0
7 0 7 0 7 0 7 0 7 0 7
7 0 0 0 7 0 0 0 7 0 7
7 0 0 0 0 7 0 0 7 7 0
7 0 0 0 0 0 7 0 7 0 0
7 0 7 0 7 0 7 0 7 0 0
0 7 0 0 0 7 0 0 7 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
样例输出:
83
参考csdn:https://blog.csdn.net/qq_44668088/article/details/115943074?spm=1001.2014.3001.5501
二维前缀和
这样的代码用了四重循环会超时,用二维前缀和计算sum[i][j],在每次计算的时候直接计算sum,复杂度O(1),最终复杂度O(n²)
70分代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<stdlib.h>
using namespace std;
struct xiangsu {
int l;//灰度
int sum;//附近的点的灰度之和
double avg;//所有元素灰度的平均值
int n;//附近的元素个数
}xiang[610][610];
int main() {
int n, L,r,t;//边长n,灰度L,大小r,阈值t
int i, j,k,q;//循环变量
int nums=0;
scanf("%d %d %d %d",&n,&L,&r, &t);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
xiang[i][j].n = 0;
xiang[i][j].sum = 0;
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &xiang[i][j].l);
for (k = 0;k < n ;k++)
{
if (k >= i - r && k <= i + r)
{
for (q = 0; q < n ; q++)
{
if (q >= j - r && q <= j + r)
{
xiang[i][j].n++;
xiang[k][q].sum += xiang[i][j].l;
}
}
}
}
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
xiang[i][j].avg = xiang[i][j].sum * 1.0 / xiang[i][j].n;
if (xiang[i][j].avg <= t)
nums++;
}
}
printf("%d",nums);
return 0;
}
sum[i][j] 存取的是从点(1,1)到点(i,j)这个区间内所有数值的和
可以推出sum[i][j] = sum[i-1][j]+sum[i][j-1] - sum[i-1][j-1]+A[i][j] 所以我们可以通过O ( n 2 ) O(n^2)O(n 2 )的时间复杂度来求得整个sum数组
如下图:绿+红-黄+蓝
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
sum[i][j] = sum[i-1][j]+sum[i][j-1] - sum[i-1][j-1]+A[i][j];
}
}
求完二维前缀,下面以O(1)的复杂度求出(xmin,ymin)到(xmax,ymax)这个黄色区域内所有元素的和
area = sum[maxx][maxy] - sum[maxx][miny-1] - sum[minx-1][maxy] + sum[minx-1][miny-1];
100分代码:
#include<iostream>
using namespace std;
int n,L,r,t,ans=0;
int A[605][605]={0};
int sum[605][605]={0};
bool judgeBlack(int x,int y)
{
int maxx = min(n, x+r);
int maxy = min(n, y+r);
int minx = max(1, x-r);
int miny = max(1, y-r);
int s = sum[maxx][maxy] - sum[maxx][miny-1] - sum[minx-1][maxy] + sum[minx-1][miny-1];
int count = (maxx-minx+1)*(maxy-miny+1);
double test = s/(double)count;
return test<=t;
}
int main()
{
cin>>n>>L>>r>>t;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>A[i][j];
sum[i][j] = sum[i-1][j]+sum[i][j-1] - sum[i-1][j-1]+A[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(judgeBlack(i,j))
ans++;
}
cout<<ans;
return 0;
}
202012-1期末预测之安全指数
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int main() {
int n, w, score;
int i;
int sum = 0;
scanf("%d",&n);
for (i = 0; i < n; i++)
{
scanf("%d %d",&w,&score);
sum += w * score;
}
if (sum >= 0)
printf("%d", sum);
else
printf("0");
return 0;
}
202012-2 期末预测之最佳阈值
样例输入:
6
0 0
1 0
1 1
3 1
5 1
7 1
样例输出:
3
样例输入:
8
5 1
5 0
5 0
2 1
3 0
4 0
100000000 1
1 0
样例输出:
100000000
参考csdn:https://blog.csdn.net/qq_45985728/article/details/114903481
二重循环排序,这样会超时,使用邻域均值,一维前缀和
70分答案:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <cctype>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 100010;
struct student {
int y;
int result;
int predict;
}stu[maxn];
bool cmp(student a, student b)
{
if (a.predict != b.predict) return a.predict > b.predict;
else return a.y > b.y;
}
int main() {
int m, i;
int j;
scanf("%d",&m);
for (i = 0; i < m; i++)
{
scanf("%d %d",&stu[i].y,&stu[i].result);
stu[i].predict = 0;
}
for (i = 0; i < m; i++)
{
for(j=0;j<m;j++)
if (stu[j].y>=stu[i].y&& stu[j].result==1|| stu[j].y < stu[i].y && stu[j].result == 0)
{
stu[i].predict++;
}
}
sort(stu,stu+m,cmp);
printf("%d",stu[0].y);
return 0;
}
70分答案-结构体版
这题的细节真的好多呀,全部思路已经和下面的100分一模一样了,但是还是超时了!!!
看来不仅思路要对,还得选正确的数据结构啊!orz
这题耗时我猜是因为用了结构体,不断在结构体里面赋值排序这些还调用cmp函数比较耗时
100分里面直接用sort自带的给pair排序,然后pre0和rear1都是直接用数组存的,估计读写较快,又是亿个小细节~
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
struct student {
int y;
int result;
int pre;//前面的0
int rear;//后面的1
int sum;
}stu[210];
bool cmp(student a, student b)
{
if (a.y != b.y)
return a.y < b.y;
else
return a.result < b.result;
}
bool cmp1(student a, student b)
{
if (a.sum != b.sum)
return a.sum > b.sum;
else
return a.y > b.y;
}
int main() {
int m;
int i;
int j;
int sum = 0;
int ans;//最后的结果
scanf("%d", &m);
for (i = 0; i < m; i++)
{
scanf("%d %d", &stu[i].y, &stu[i].result);
stu[i].sum = 0;
stu[i].pre = 0;
stu[i].rear = 0;
}
sort(stu, stu + m, cmp);
if (stu[0].result == 0)
stu[0].pre = 1;
else
stu[0].pre = 0;
for (i = 1; i < m; i++)
{
if (stu[i].result == 0)
{
stu[i].pre = stu[i - 1].pre + 1;//下一个阈值的pre为1
}
else
{
stu[i].pre = stu[i - 1].pre;//下一个阈值的pre为0
}
}
if(stu[m-1].result==1)
stu[m-1].rear = 1;
else
stu[m-1].rear = 0;
for (i = m - 2; i >= 0; i--)
{
if (stu[i].result == 1)
{
stu[i].rear = stu[i + 1].rear + 1;//上一个阈值的rear为2
}
else//等于0,那么
{
stu[i].rear = stu[i + 1].rear;//上一个阈值的rear为0
}
}
/*for (i = 0; i < m; i++)
{
stu[i].sum=stu[i].rear+stu[i-1].pre;
printf("i=%d,y=%d,pre=%d,last=%d,sum=%d\n",i,stu[i].y,stu[i].pre,stu[i].rear,stu[i].sum);
}*/
sum = stu[0].rear;
ans = stu[0].y;
for (i = 1; i < m; i++)
{
if (stu[i].y == stu[i - 1].y)//这种情况一定是后一个比前一个多1,但是不可取,因为前一个是相等的,后一个的统计无效,或者后一个和前一个一样,(无需统计,在前面统计过了),
continue;//只要看前一个就可以了,continue直接跳过当前的循环,进入下一个循环
if (sum <= stu[i - 1].pre + stu[i].rear)//注意要等于,因为这样才能取到序号最大的
sum = stu[i - 1].pre + stu[i].rear, ans = stu[i].y;
}
printf("%d", ans);
return 0;
}
100分答案pair版:
注意sort对pair进行排序的时候,首先对第一数排序,如果first相同,就对second排序
#include<iostream>
#include<algorithm>
using namespace std;
pair<int,int> pii[100005]; //pair数组储存信息,每个pair存储一个同学的y和result
int pre0[100005]; //记录该位置及前面的result为0的个数(前缀和)
int rear1[100005]; //记录该位置及后面的result为1的个数(后缀和)
int k = -1,ma = 0; //k用来记录最佳阈值,ma用来存储最佳阈值对应的预测成国公数目
int main(){
int m;
cin>>m; //输入m
pii[0] = pair<int,int>(-1,-1);
for(int i = 1;i <= m;++i) //初始化pii数组
cin>>pii[i].first>>pii[i].second;
sort(pii + 1,pii + 1 + m); //将所有学生信息按照阈值从小到大排序,方便后续前缀后缀和的操作
for(int i = 1;i <= m;++i) //记录前缀0个数
if(pii[i].second == 0)
pre0[i] = pre0[i - 1] + 1;
else
pre0[i] = pre0[i - 1];
for(int i = m;i >= 1;--i) //记录后缀1个数
if(pii[i].second == 1)
rear1[i] = rear1[i + 1] + 1;
else
rear1[i] = rear1[i + 1];
for(int i = 1;i <= m;++i){ //最终处理
if(pii[i].first == pii[i - 1].first)
continue; //如果有阈值相同的情况,那么在相同区间的第一个位置统计了,直接跳过
if(ma <= pre0[i - 1] + rear1[i])//更新k和ma
ma = pre0[i - 1] + rear1[i],k = pii[i].first;
}
cout<<k;
return 0;
}
202009-1 称检测点查询
常规题目
202009-2 风险人群筛查
常规题目,这题竟然没有一点套路,好感人
202006-1 线性分类器
1.用sum计算求得的函数值,如果两个点的函数值相乘大于0,说明这两个点属于同一类,重点是if函数的判断,因为int类型只有10的9次方,而题目最大可以到10的12次方,所以需要用long long来存储sum
2.在判断两个点的sum是否同号时,不要用相乘的结果大于零判断,因为这样一样的会让结果越界,所以直接判断即可
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<stdlib.h>
using namespace std;
const int maxn = 1010;
struct dian{
int x;
int y;
char type;
long long int sum;
}dia[maxn];
int main() {
int n, m;
int i,j;
int num1, num2, num3;
int flag;
scanf("%d %d",&n,&m);
for (i = 0; i < n; i++)
{
scanf("%d %d %c",&dia[i].x,&dia[i].y,&dia[i].type);
}
for (i = 0; i < m; i++)
{
flag = 1;
scanf("%d %d %d",&num1,&num2,&num3);
for (j = 0; j < n; j++)
{
dia[j].sum = num1 + num2 * dia[j].x + num3 * dia[j].y;
}
for (j = 0; j < n-1; j++)
{
if (((dia[j].sum >0&& dia[j + 1].sum > 0|| dia[j].sum < 0 && dia[j + 1].sum < 0) && (dia[j].type != dia[j + 1].type ))|| ((dia[j].sum >0&& dia[j + 1].sum < 0 || dia[j].sum <0 && dia[j + 1].sum > 0)&&( dia[j].type == dia[j + 1].type)))//重点是这个判断
{
flag = 0;
break;
}
}
if (flag == 0)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}
202006-2 稀疏向量
样例输入
10 3 4
4 5
7 -3
10 1
1 10
4 20
5 30
7 40
样例输出
-20
1、一开始用hash表来表示在v中的下标有没有出现过,但是后来n取到了10的9次方,取hashtable[1000000010],实在是太大了,程序会编译不通过
2、使用map来建立两个元素之间的映射关系,当向量v中出现新的下标和元素值的时候,就把<下标,元素值>记录到map中
3、在向量u输入的时候mp.find(向量u的下标),如果该下标出现过,那么计算sum+=元素1*元素2,这里注意元素1和元素2都要取long long int ,因为从测试用例4之后元素的乘积可能大于Int的范围。
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<map>
#include<utility>
using namespace std;
map<long int,long int> mp;
int main() {
int n, a, b;
int i;
long long int sum = 0;
long long int temp1, temp2;
map<long int,long int>::iterator it;
scanf("%d %d %d",&n,&a,&b);
for (i = 1; i <=a; i++)
{
scanf("%lld %lld", &temp1, &temp2);
mp.insert(pair<long int, long int>(temp1, temp2));
}
for (i = 1; i <= b; i++)
{
scanf("%lld %lld", &temp1, &temp2);
it = mp.find(temp1);
if (it!= mp.end())
sum += it->second * temp2;
}
printf("%lld",sum);
return 0;
}
201912-1 报数
这题需要审题n到底是什么,一开始没有看好题目,花了好长时间
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<map>
#include<utility>
using namespace std;
//此函数用来判断n是否需要被跳过
int judge(int n)
{
int flag = 1;//
int temp;
if (n % 7 == 0)
flag = 0;
else
{
while (n != 0)
{
temp = n % 10;
if (temp == 7)
{
flag = 0;
break;
}
n /= 10;
}
}
return flag;
}
int main() {
int n;
int a[5] = {0};
int lun=1;//表示第几轮
int num=1;
scanf("%d",&n);//取到n的值
while(n!=0)
{
if (judge(num))//正常的数
{
n--;//剩下还可以报出的数-1
}
else
{
a[lun % 4]++;
}
num++;
lun++;//要注意不管是正常的数还是跳过的数,都算一轮;
}
printf("%d\n%d\n%d\n%d\n", a[1], a[2], a[3], a[0]);
return 0;
}
201912-2 回收站选址
1、这题一开始想用map映射来存储坐标x和坐标y,后来发现Map只能做到一一映射,也就是它的一个横坐标只能对应一个纵坐标,所以不能同时存下(2,1)与(2,2),所以还是老老实实用结构体来存储,因为题目说n最多是1000,所以结构体还不算很大
2、我发现csp的第二题只要复杂度控制在n²内就不会超时了,20年12月的除外,注意这个题目是怎么判断的,首先十字架坐标垃圾堆4个都要有,然后再对角线坐标垃圾堆的个数决定得分。
但是如果先判断十字架坐标满足,然后再遍历一遍找对角线的格数,复杂度变为2n²了
3、所以不管这个点符不符合,都先把对角线垃圾堆的个数记录下来,如果十字架格数为4了,直接赋值,让时间少了一半
4、最后一点是怎么判断十字架垃圾堆和对角线垃圾堆。一开始我使用逐个对比x和y坐标的方法,发现这样代码冗长,可以直接计算两者x和y坐标的差的绝对值,如果绝对值之和=1,表示是十字架垃圾堆,绝对值之和=2,并不能表示是对角线垃圾堆,因为有可能是(10,10)和(12,10),这个时候要看横纵坐标差的绝对值分别为1!一开始没有注意到,只能过两个测试点。
5、这题很巧妙的让坐标都小于10的9次方,所以不管是正负数加或者减都不会超过Int的范围,感动
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<map>
#include<utility>
using namespace std;
struct dian {
int x;
int y;
}dia[1010];
int main() {
int n;
int i,j;
int score;
int scores[5] = { 0 };
int flag;
scanf("%d",&n);//取到n的值
for (i = 0; i < n; i++)
scanf("%d %d",&dia[i].x,&dia[i].y);
for (i = 0; i < n; i++)
{
score = 0;
flag = 0;
for (j = 0; j < n; j++)
{
if (abs(dia[j].x - dia[i].x)+abs(dia[j].y - dia[i].y)== 1)
{
flag ++;
}
//这里要注意
else if (abs(dia[j].x - dia[i].x)==1&&abs(dia[j].y - dia[i].y) == 1)
{
score++;
}
}
if (flag == 4)
{
scores[score]++;
}
}
for (i = 0; i <= 4; i++)
printf("%d\n",scores[i]);
return 0;
}
201909-1 小明种苹果
这题一开始在for循环后面加了括号,找了半天没找出来,又是亲爱的小伙伴帮我找出来的,菜鸡如我orz
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<map>
#include<utility>
using namespace std;
const int maxn = 1010;
struct Tree {
int ori;
int sum;//摘掉的苹果总数
}tree[maxn];
int main() {
int n,m;
int i,j;
int temp;
int T= 0;
int k = 0;
scanf("%d %d",&n,&m);
for (i = 0; i < n; i++)
{
scanf("%d",&tree[i].ori);
T += tree[i].ori;
tree[i].sum = 0;
j = 0;
for (j = 0; j < m; j++)
{
scanf("%d",&temp);
tree[i].sum += temp;
}
T += tree[i].sum;
if (tree[i].sum < tree[k].sum)
k = i;
}
printf("%d %d %d",T,k+1,-tree[k].sum);
return 0;
}
201909-2 小明种苹果(续)
这题有一点,就是一棵树可能小明统计了很多次果子数量,当一棵树掉很多次果子的时候,D也只是+1,所以需要用flag来判断,不能每次掉果子都让D+1
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<map>
#include<utility>
using namespace std;
const int maxn = 1010;
int main() {
int n,m;
int i,j;
int temp;
int T[maxn] = {0};//表示现在第i棵树上还有几颗果子
int a[maxn] = { 0 };//记录第i棵树有没有掉果子
int D = 0;
int E = 0;
int TT=0;
int flag;
scanf("%d",&n);
for (i = 0; i < n; i++)
{
flag = 0;
scanf("%d", &m);
scanf("%d", &T[i]);
for (j = 0; j < m-1; j++)
{
scanf("%d",&temp);
if (temp <= 0)//进行了疏果操作
{
T[i] += temp;
}
else//统计了当前树上的果子数量
{
if (T[i] > temp)//说明掉了果子
{
T[i] = temp;
flag = 1;
a[i] = 1;//记录这颗苹果树的果子掉了
}
}
}
if (flag == 1)
D++;
}
for (i = 0; i < n; i++)
{
if (a[i % n] == 1 && a[(i + 1) % n] == 1 && a[(i + 2) % n] == 1)
E++;
TT += T[i];
}
printf("%d %d %d",TT,D,E);
return 0;
}
201903-1 小中大
这题说最多保留一位小数四舍五入这些,本来输入的是整数,最多也就.5的小数啊,中间格式化输出%g或者%f的时候总是报错,拿90或者70分
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<map>
#include<utility>
using namespace std;
const int maxn = 100010;
int a[maxn] = { 0 };
int main() {
int n;
int i;
scanf("%d",&n);
for (i = 0; i < n; i++)
{
scanf("%d",&a[i]);
}
sort(a, a + n);
int max, min, mid;
max = a[n-1];
min = a[0];
if (n & 1)
{
mid = a[n / 2];
printf("%d %d %d", max, mid , min);
}
else
{
mid = a[n / 2] + a[n / 2 - 1];
if (mid & 1)
printf("%d %d.5 %d", max, mid / 2, min);
else
printf("%d %d %d", max, mid / 2, min); }
return 0;
}
201903-2 二十四点
1、首先不能用字符存储乘号×,这样会输出?如下:
所以选择用字符串存储,在栈中计算。
另外当出现减法的时候将它转换为加法,让j++,这个想法也很巧妙
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int n;
char str[10];
stack<int> num;//数字栈
stack<char> sign;//符号栈
int main() {
scanf("%d", &n);
getchar(); //读取留在缓冲区的换行符
for (int i = 0; i < n; i++) {
scanf("%s",str);
while (!num.empty()) num.pop(); //清空栈
while (!sign.empty()) sign.pop();
int j = 0;
while (j < strlen(str)) {
if (str[j] > '0' && str[j] <= '9') {
num.push(str[j] - '0');
}
else {
if (str[j] == '+') {
sign.push('+');
}
else if (str[j] == '-') { //将减法转换成加法
num.push((str[j + 1] - '0') * (-1));
sign.push('+');
j++;
}
else if (str[j] == 'x') { //直接计算乘法
int lhs = num.top();
num.pop();
num.push(lhs * (str[j + 1] - '0'));
j++;
}
else if (str[j] == '/') { //直接计算除法
int lhs = num.top();
num.pop();
num.push(lhs / (str[j + 1] - '0'));
j++;
}
}
j++;
}
while (!sign.empty()) { //计算剩余的加法
int rhs = num.top();
num.pop();
int lhs = num.top();
num.pop();
sign.pop();
num.push(lhs + rhs);
}
int ans = num.top();
if (ans == 24) printf("Yes\n");
else printf("No\n");
}
return 0;
}
201812-1 小明上学
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int main() {
int r, y, g;
scanf("%d %d %d",&r,&y,&g);
int n;
int i;
scanf("%d", &n);
int sum = 0;//上学的总时长
int temp1, temp2;
for (i = 0; i < n; i++) {
scanf("%d %d",&temp1,&temp2);
if (temp1 == 0)
sum += temp2;
else if (temp1 == 1)//如果遇到红灯,等待
sum += temp2;
else if (temp1 == 2)//雨打黄德国,等待黄灯+红灯
sum += temp2 + r;
else//遇到绿灯,直接通行
;
}
printf("%d", sum);
return 0;
}
201812-2小明放学
这题做好分类讨论就可以啦,注意后面4个测试单要取到long long int才可以
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int main() {
int r, y, g;
scanf("%d %d %d",&r,&y,&g);
int n;
int i;
scanf("%d", &n);
long long int sum = 0;//上学的总时长
long long int temp1, temp2;
int t = 0;//表示到当前路口时已经过去的时间
for (i = 0; i < n; i++)
{
scanf("%lld %lld",&temp1,&temp2);
if (temp1 == 0)
{
sum += temp2;//总时长+
}
else
{
temp2 -= sum;//一开始的时长减去已经过去的时长
if (temp1 == 1)//表示一开始是红灯
{
if(temp2 >=0)//说明现在还是红灯,等过这个绿灯就可以了
sum += temp2;
else//说明已经变灯了
{
temp2 = -temp2;//从绿灯开始算,又过去了temp2秒
temp2 %= r + y + g;//算在一个周期里面
if (temp2 <= g)
;//直接通过
else //是黄灯或者红灯
sum += (g + y + r - temp2);//等红灯的时间
}
}
else if (temp1 == 2)//表示当前是黄灯
{
if (temp2 >= 0)//说明现在还是黄灯,等过这个黄灯+红灯就可以了
sum += temp2 + r;
else
{
temp2 = -temp2;
temp2 %= r + y + g;//算在一个周期里面
if (temp2 <= r)//说明现在是红灯
sum += r - temp2;
else if (temp2 <= r + g)
;//绿灯,直接通过
else//黄灯
sum += (r + g + y - temp2) + r;//等黄灯的时间+等红扽的时间
}
}
else//表示当前是绿灯
{
if (temp2 >= 0)//说明现在还是绿灯,
;
else
{
temp2 = -temp2;
temp2 %= r + y + g;//算在一个周期里面
if (temp2 <= y + r)//现在是黄灯
sum += y + r - temp2;
else//说明又到了绿灯
;//通过
}
}
}
}
printf("%lld", sum);
return 0;
}
201809-1 卖菜
这题需要注意第二天的价格要再开一个数组存放,不然之后算平均的时候价格已经改变了。
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 1010;
int shop1[maxn] = { 0 };
int shop2[maxn] = { 0 };
int main() {
int n;
scanf("%d",&n);
int i;
for (i = 0; i < n; i++)
{
scanf("%d",&shop1[i]);
}
for (i = 1; i < n - 1; i++)
{
shop2[i] = (shop1[i - 1] + shop1[i] + shop1[i + 1])/3;
}
shop2[0] = (shop1[0] + shop1[1]) / 2;
shop2[n-1]= (shop1[n-1] + shop1[n-2]) / 2;
for (i = 0; i < n; i++)
{
printf("%d ",shop2[i]);
}
return 0;
}
201809-2 买菜
考察结构体存放,没有坑,复杂度n²
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 1000010;
struct hash {
int id;
int biaoji;
}hashtable[maxn];
int main() {
int n;
scanf("%d",&n);
int i,j;
int temp1, temp2;
int sum=0;
//首先初始化
for (i = 0; i < n; i++)
{
hashtable[i].id = hashtable[i].biaoji = 0;
}
for (i = 1; i <=n; i++)
{
scanf("%d %d",&temp1,&temp2);
for (j = temp1; j <= temp2; j++)
{
hashtable[j].id = 1;
hashtable[j].biaoji = i;//同一个时间段的标记相同
}
}
for (i = 1; i <= n; i++)
{
scanf("%d %d", &temp1, &temp2);
for (j = temp1; j < temp2; j++)
{
if (hashtable[j].id == 1&&hashtable[j+1].id==1&&hashtable[j].biaoji==hashtable[j+1].biaoji)
sum++;
}
}
printf("%d",sum);
return 0;
}
201803-1 跳一跳
简单的判断
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int main() {
int n;
int scores = 0;
int score=1;//每一局的得分
while (scanf("%d", &n), n != 0)
{
if (n == 1)
score = 1;
else
{
if (score == 1)
score = 2;
else
score += 2;
}
scores += score;
}
printf("%d",scores);
return 0;
}
201803-2 碰撞的小球
1、注意最后输出小球的时候要按照当时输入的顺序输出,所以结构体里面要加上一个id来标识
2、sort排序的时候注意下标
3、定义flag=1或者=-1来表示是向右还是向左走,下一个时刻的位置=上一个时刻的位置+flag
4、这题很贴心的说了没有三个小球同时相撞,不然要搜索三个甚至更多在同一坐标的小球复杂度又会上去了
5、老问题,复杂度控制在n²就Ok,
6、感觉这两年的题目都是考一些分类,思路理清楚就好了
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
struct Ball {
int a;//表示小球的位置
int flag;//表示小球的方向1表示向右,-1表示向左
int id;
}ball[110];
bool cmp1(Ball a,Ball b)
{
if (a.a != b.a)
return a.a < b.a;
else if(a.flag!=b.flag)return a.flag > b.flag;
else return a.id < b.id;
}
bool cmp2(Ball a, Ball b)
{
return a.id < b.id;
}
int main() {
int n,L,t;
scanf("%d %d %d",&n,&L,&t);
int i;
int j;
for (i = 1; i <= n; i++)
{
scanf("%d",&ball[i].a);
ball[i].flag = 1;
ball[i].id = i;
}
for (j = 1; j <= t; j++)//t秒之后
{
//时刻j
sort(ball+1, ball + n+1, cmp1);
//下面改变方向
//首先考虑有没有在位置0和位置L的
for (i = 1; i <= n; i++)
{
if (ball[i].a == 0 || ball[i].a == L)
ball[i].flag *= -1;
}
//然后考虑一般情况
for (i = 1; i < n; i++)
{
if (ball[i].a == ball[i + 1].a && ball[i].flag != ball[i + 1].flag)
{
swap(ball[i].flag, ball[i + 1].flag);
i++;//题目保证了不会有三个小球同时相撞
}
}
//下面移动距离
for (i = 1; i <= n; i++)
{
ball[i].a += ball[i].flag;
}
}
sort(ball + 1, ball + n + 1, cmp2);
for (i = 1; i <= n; i++)
{
printf("%d ", ball[i].a);
}
return 0;
}
201712-1 最小差值
基础题
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
int a[1010] = { 0 };
int main() {
int n;
int min;
int i;
int temp;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
sort(a, a + n);
min = a[1] - a[0];
for (i = 1; i < n-1; i++)
{
temp = a[i + 1] - a[i];
if (temp < min)
swap(temp, min);
}
printf("%d",min);
return 0;
}
201712-2 游戏
一样是绕逻辑的一道题目
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
int hashtable[1010] = { 0 };
int main() {
int n;
int k;
scanf("%d %d",&n,&k);
int i=0;//表示当前报数的小朋友编号
int nums = 1;//当前报的数字
int num=n;//剩下的小朋友的个数;
for(i=0;num>1;)//
{
i++;//小朋友编号+1
if (hashtable[i % n] == 1)//如果当前小朋友已经被淘汰了
continue;
else
{
//printf("当前%d号小朋友报数%d\n", i % n, nums);
if (nums % k == 0 || nums % 10 == k)
{
hashtable[i % n] = 1;
num--;
//淘汰
}
}
nums++;
}
for (i = 0; i < n; i++)
{
if (hashtable[i] == 0)
break;
}
if (i % n == 0)
printf("%d",n);
else
printf("%d",i%n);
return 0;
}
201709-1打酱油
基础题
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
int main() {
int n;
scanf("%d",&n);
int sum = 0;
if (n >= 50)
sum += n / 50 * 7;
n = n - n / 50 * 50;
if (n >= 30)
sum += n / 30 * 4;
n = n - n / 30 * 30;
sum += n / 10;
printf("%d",sum);
return 0;
}
201709-2 公共钥匙盒
同样是结构体+逻辑,涉及排序
一开始我想要定老师为一个结构体,后来发现应该把取钥匙或者还钥匙的操作定义为一个结构体
1、当换完钥匙之后立即break
2、注意结构体排序函数cmp的编写
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 2010;
struct yaoshi {
int id;//钥匙的编号
int time;//借或者还的时间
int flag;//表示是换钥匙还是取钥匙,flag=-1表示取钥匙,flag=1表示还钥匙
}Yao[maxn];
bool cmp(yaoshi a, yaoshi b)
{
if (a.time != b.time)//首先按照时间顺序排序
return a.time < b.time;
else if (a.flag != b.flag) return a.flag > b.flag;//如果时间相同,就先换钥匙,再取钥匙
else//如果还的时间相同,就按照id大小还钥匙
return a.id < b.id;
}
int main() {
int n,k;
int i;
int j;
int id;
int a[maxn] = {0};//0表示没有钥匙在上面,n表示n号钥匙在上面
scanf("%d %d",&n,&k);
//初始化钥匙盒
for (i = 1; i <= n; i++)
{
a[i] = i;
}
//初始化钥匙,并排序
for (i = 1; i <=2*k; i+=2)//一共2k个操作
{
scanf("%d",&id);
scanf("%d %d", &Yao[i].time, &Yao[i+1].time);
Yao[i].id = Yao[i+1].id = id;
Yao[i + 1].time += Yao[i].time;
Yao[i].flag = -1;//取钥匙
Yao[i+1].flag = 1;//还钥匙
}
sort(Yao+1, Yao + 2*k+1, cmp);
for (i = 1; i <=2*k; i++)//遍历2*k次钥匙操作
{
if (Yao[i].flag == -1)//如果是取钥匙
{
for (j = 1; j <= n; j++)
if (a[j] == Yao[i].id)
{
a[j] = 0;
break;
}
}
else//还钥匙
{
for (j = 1; j <= n; j++)
if (a[j] == 0)
{
a[j] = Yao[i].id;//这里注意还完钥匙,不用再寻找后面空的钥匙位了
break;
}
}
}
for (j = 1; j <= n; j++)
printf("%d ", a[j]);
return 0;
}
201703-1 分蛋糕
基础题
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 2010;
int main() {
int n, k;
scanf("%d %d",&n,&k);
int num = 0;//最终分到蛋糕的数量
int i;
int temp;
int sum = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &temp);
sum += temp;
if (sum >= k)
{
num++;
if (i == n - 1)//如果是最后一块蛋糕了,那么sum不需要清零了
break;
sum = 0;
}
}
if (sum < k)//如果蛋糕分完了还是不够k
num++;
printf("%d",num);
return 0;
}
201703-2 学生排队
也是一道逻辑题,一些细节注意一下即可
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
const int maxn = 1010;
struct student {
int id;
int weizhi;
}stu[maxn];
bool cmp(student a, student b)
{
return a.weizhi < b.weizhi;
}
int main() {
int n,m;
scanf("%d%d",&n,&m);
int i,j;
int temp1, temp2;
int flag = 0;
for (i = 1; i <= n; i++)
{
stu[i].id = i;
stu[i].weizhi = i;
}
for (j = 1; j <= m; j++)
{
sort(stu + 1, stu + n + 1, cmp);
/*for (i = 1; i <= n; i++)
{
printf("%d ", stu[i].id);
}*/
flag = 0;
scanf("%d %d",&temp1,&temp2);
if (temp2 == 0)//啥也不做
;
else if (temp2 < 0)//说明要向前移动
{
for (i = n; i >=1 && temp2 != 0; i--)
{
if (flag == 1)
{
stu[i].weizhi++;
//printf("stu[%d].weizhi++,=%d\n", i, stu[i].weizhi);
temp2++;
}
if (stu[i].id == temp1 && flag == 0)
{
stu[i].weizhi += temp2;
flag = 1;
}
}
}
else//向后移动
{
for (i = 1; i <= n&&temp2!=0; i++)
{
if (flag == 1)
{
//printf("!!!\n");
stu[i].weizhi--;
//printf("stu[%d].weizhi--,=%d\n", i, stu[i].weizhi);
temp2--;
}
if (stu[i].id == temp1&&flag==0)
{
stu[i].weizhi += temp2;
flag = 1;
}
}
}
}
sort(stu + 1, stu + n + 1, cmp);
for (i = 1; i <= n; i++)
{
printf("%d ", stu[i].id);
}
return 0;
}
201612-1 中间数
基础题,这题本来想用set自动去重然后排序,但是后来发现不仅中数会重复,大数和小数一样会重复,所以还是老实用数组叭,复杂度n²
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 1010;
int a[maxn];
int main() {
int n;
scanf("%d",&n);
int i,j;
int left, right;
for (i = 0; i < n; i++)
{
scanf("%d",&a[i]);
}
sort(a, a + n);//排序
for (i = 0; i < n; i++)
{
left = right = 0;
for (j = 0; j < n; j++)
if (a[j] < a[i])
left++;
else if (a[j] > a[i])
right++;
if (left == right)
{
printf("%d",a[i]);
return 0;
}
}
printf("-1");
return 0;
}
201612-2 工资计算
这题好奇怪哟,没有四舍五入,用%g输出反而是对的,用四舍五入了输出就错了,直接cout<<输出也是对的,这样反过来做相当于做了一道数学题,,但是复杂度为0,如果正过来也可以复杂度n
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int main() {
int T;
double S;
scanf("%d",&T);
if (T <= 3500)
S = T;
else if (T <= 4955)
S = (T - 105) * 1.0 / 0.97;
else if (T <= 7655)
S = (T - 455) * 1.0 / 0.9;
else if (T <= 11255)
S = (T - 1255) * 1.0 / 0.8;
else if (T <= 30755)
S = (T - 1880) * 1.0 / 0.75;
else if (T <= 44755)
S = (T - 3805) * 1.0 / 0.7;
else if (T <= 61005)
S = (T - 6730) * 1.0 / 0.65;
else
S = (T - 15080) * 1.0 / 0.55;
//下面四舍五入
//if (int(S) % 100 >= 50)
// S = (S / 100 + 1) * 100;
//else
// S = (S / 100 ) * 100;
printf("%g", S);
//cout << S << endl;
return 0;
}
201609-1 最大波动
基础题
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 10000;
int a[maxn] = { 0 };
int main() {
int n;
scanf("%d",&n);
int max = 0;
int temp;
for (int i = 0; i < n; i++)
{
scanf("%d",&a[i]);
}
for (int i = 0; i < n-1; i++)
{
temp = abs(a[i + 1] - a[i]);
if (temp > max)
max = temp;
}
printf("%d",max);
return 0;
}
201609-2 火车购票
逻辑题,分类讨论
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int a[21][6];//20排,每排5个座位
int main() {
int n;
int i, num,j;
int hang, lie;
int flag;//=0表示没有找到连号的座位,反
scanf("%d",&n);
for (i = 1; i <=20; i++)
for (j = 1; j <=5; j++)
a[i][j] = 1;//表示有座位
for (i = 0; i < n; i++)
{
flag = 0;
scanf("%d",&num);
//下面找合适的座位;
if (num == 1)
{
for (hang = 1; hang <= 20; hang++)
{
for (lie = 1; lie <= 5; lie++)
{
if (a[hang][lie] == 1)
{
printf("%d\n", (hang - 1) * 5 + lie);
a[hang][lie] = 0;
flag=1;
break;
}
}
if (flag == 1)
break;
}
}
else if (num == 2)
{
for (hang = 1; hang <= 20; hang++)
{
for (lie = 1; lie <= 5-num+1; lie++)
{
if (a[hang][lie] == 1 && a[hang][lie + 1] == 1)
{
flag = 1;
printf("%d %d\n",(hang - 1) * 5 + lie, (hang - 1) * 5 + lie+1);
a[hang][lie] = 0;
a[hang][lie + 1] = 0;
break;
}
}
if (flag == 1)
break;
}
if (flag == 0)//没有找到连续的座位
{
for (hang = 1; hang <= 20; hang++)
{
for (lie = 1; lie <= 5 ; lie++)
{
if (a[hang][lie] == 1)
{
printf("%d ", (hang - 1) * 5 + lie);
a[hang][lie] = 0;
num--;
}
if (num == 0)
{
printf("\n");
break;
}
}
if (num == 0)
break;
}
}
}
else if (num == 3)
{
for (hang = 1; hang <= 20; hang++)
{
for (lie = 1; lie <= 5 - num + 1; lie++)
{
if (a[hang][lie] == 1 && a[hang][lie + 1] == 1&&a[hang][lie+2]==1)
{
flag = 1;
printf("%d %d %d\n", (hang - 1) * 5 + lie, (hang - 1) * 5 + lie + 1, (hang - 1) * 5 + lie + 2);
a[hang][lie] = 0;
a[hang][lie + 1] = 0;
a[hang][lie + 2] = 0;
break;
}
}
if (flag == 1)
break;
}
if (flag == 0)//没有找到连续的座位
{
for (hang = 1; hang <= 20; hang++)
{
for (lie = 1; lie <= 5; lie++)
{
if (a[hang][lie] == 1)
{
printf("%d ", (hang - 1) * 5 + lie);
a[hang][lie] = 0;
num--;
}
if (num == 0)
{
printf("\n");
break;
}
}
if (num == 0)
break;
}
}
}
else if (num == 4)
{
for (hang = 1; hang <= 20; hang++)
{
for (lie = 1; lie <= 5 - num + 1; lie++)
{
if (a[hang][lie] == 1 && a[hang][lie + 1] == 1 && a[hang][lie + 2] == 1&& a[hang][lie + 3] == 1)
{
flag = 1;
printf("%d %d %d %d\n", (hang - 1) * 5 + lie, (hang - 1) * 5 + lie + 1, (hang - 1) * 5 + lie + 2, (hang - 1) * 5 + lie + 3);
a[hang][lie] = 0;
a[hang][lie + 1] = 0;
a[hang][lie + 2] = 0;
a[hang][lie + 3] = 0;
break;
}
}
if (flag == 1)
break;
}
if (flag == 0)//没有找到连续的座位
{
for (hang = 1; hang <= 20; hang++)
{
for (lie = 1; lie <= 5; lie++)
{
if (a[hang][lie] == 1)
{
printf("%d ", (hang - 1) * 5 + lie);
a[hang][lie] = 0;
num--;
}
if (num == 0)
{
printf("\n");
break;
}
}
if (num == 0)
break;
}
}
}
else
{
for (hang = 1; hang <= 20; hang++)
{
if (a[hang][1] == 1 && a[hang][2] == 1 && a[hang][3] == 1&&a[hang][4]==1&&a[hang][5]==1)
{
flag = 1;
printf("%d %d %d %d %d\n", (hang - 1) * 5 + 1, (hang - 1) * 5 + 2, (hang - 1) * 5 +3, (hang - 1) * 5 + 4, (hang - 1) * 5 + 5);
a[hang][1] = 0;
a[hang][2] = 0;
a[hang][3] = 0;
a[hang][4] = 0;
a[hang][5] = 0;
break;
}
}
if (flag == 0)//没有找到连续的座位
{
for (hang = 1; hang <= 20; hang++)
{
for (lie = 1; lie <= 5; lie++)
{
if (a[hang][lie] == 1)
{
printf("%d ", (hang - 1) * 5 + lie);
a[hang][lie] = 0;
num--;
}
if (num == 0)
{
printf("\n");
break;
}
}
if (num == 0)
break;
}
}
}
}
return 0;
}
201604-1折点计数
基础题
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 1010;
int a[maxn] = { 0 };
int main() {
int n;
int i;
int num = 0;
scanf("%d",&n);
for (i = 0; i < n; i++)
{
scanf("%d",&a[i]);
}
for (i = 1; i < n - 1; i++)
{
if( (a[i]<a[i - 1] && a[i]<a[i + 1] )||( a[i]>a[i - 1] && a[i]>a[i + 1]))
num++;
}
printf("%d",num);
return 0;
}
201604-2 俄罗斯方块
这一题注意不能只对比最后一行有效行,需要对比b中的所有行才可以,同时最后一行有冲突,和没有行有冲突,这两种情况是不一样的。
下面几个容易出错的测试样例;
样例1:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 0 1 0 1 1 1 1
0 0 0 0 1 0 0 0 0 0
0 0 0 0
0 0 0 0
0 1 1 1
0 0 0 1
3
样例2:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 0 1 0 1 1 1 1
0 0 0 0 1 0 0 0 0 0
1 0 0 0
1 0 0 0
1 0 0 0
1 0 0 0
3
AC代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int a[16][11];
int b[5][5];
int main() {
int n;
int i,j;
int k;
//输入变量
for(i=1;i<=15;i++)
for (j = 1; j <=10; j++)
{
scanf("%d",&a[i][j]);
}
for (i = 1; i <= 4; i++)
for (j = 1; j <= 4; j++)
{
scanf("%d",&b[i][j]);
}
scanf("%d",&n);//第n列
//下面找有冲突的行和列
int ctRow=0;//数组a中的冲突行
int ctRow1;//数组b中的冲突行
int row;//数组b有效的行数
int hang = 1;//循环变量
//记录下b[][]中不为1的最下面一行row
for (i = 4; i >= 1; i--)//从下向上遍历
{
if (b[i][1] != 0||b[i][2]!=0||b[i][3]!=0||b[i][4]!=0)
{
row = i;
break;
}
}
//不断向下直到走不动!注意这里容易出错,不能只看最后一行有没有冲突,要遍历1-row行,j即是有冲突的行
for (i = 1; i+row-1 <=15; i++)
{
hang = 1;
for (j = i; j <= i + row-1; j++)
{
//printf("现在对比到数组a第%d行,数组b第%d行\n",j,hang);
if (a[j][n] + b[hang][1] == 2 || a[j][n + 1] + b[hang][2] == 2 || a[j][n + 2] + b[hang][3] == 2 || a[j][n + 3] + b[hang][4] == 2)
{
//printf("!!!\n");
ctRow = j;
ctRow1 = hang;
break;
}
hang++;
}
if (ctRow !=0)
break;
}
if (ctRow == 0)//如果一直没有冲突
{
j = 15-row+1;
for (hang=1; hang <= row;hang++ )//一共ctRow行
{
a[j][n] += b[hang][1]; a[j][n + 1] += b[hang][2]; a[j][n + 2] += b[hang][3]; a[j][n + 3] += b[hang][4];
j++;
}
}
else//如果有冲突的行
{
hang = 1;
j = ctRow -ctRow1;
for (; hang <= row; )//一共ctRow行
{
a[j][n] += b[hang][1]; a[j][n + 1] += b[hang][2]; a[j][n + 2] += b[hang][3]; a[j][n + 3] += b[hang][4];
hang++;
j++;
}
}
//输出结果
for (i = 1; i <= 15; i++)
{
for (j = 1; j <= 10; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
201512-1 数位之和
好基础
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int main() {
int a;
int sum=0;
scanf("%d",&a);
while (a != 0)
{
sum += a % 10;
a /= 10;
}
printf("%d",sum);
return 0;
}
201512-2 消除类游戏
hashtable存储即可
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int a[30][30];
int hashtable[30][30];
int main() {
int m, n;
int i, j;
scanf("%d %d",&n,&m);
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
scanf("%d",&a[i][j]);
hashtable[i][j] = 0;
}
}
//先遍历每一行
for (i = 0; i < n; i++)
{
for (j = 0; j <= m - 3; j++)
{
if (a[i][j] == a[i][j + 1] && a[i][j + 1] == a[i][j + 2])
{
hashtable[i][j] = 1;
hashtable[i][j + 1] = 1;
hashtable[i][j + 2] = 1;
}
}
}
for (j = 0; j < m; j++)
{
for (i = 0; i <= n - 3; i++)
{
if (a[i][j] == a[i+1][j] && a[i+1][j] == a[i+2][j])
{
hashtable[i][j] = 1;
hashtable[i+1][j] = 1;
hashtable[i+2][j] = 1;
}
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
if (hashtable[i][j] == 1)
printf("0 ");
else
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}
201509-1 数列分段
基础题
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int main() {
int n, num, i;
int duibi;
int duan;
scanf("%d",&n);
scanf("%d",&num);
duibi = num;
duan = 1;
for (i = 1; i < n; i++)
{
scanf("%d", &num);
if (num != duibi)
{
duan++;
duibi = num;
}
}
printf("%d",duan);
return 0;
}
201509-2日期处理
基础的日期处理,设置一个二位数组存放各个月份的日期即可
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int mouths[2][13] = { {0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31} };
int main() {
int year, days;
int mouth=0, day;
scanf("%d %d",&year,&days);
int flag;
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
flag = 1;
else
flag = 0;
while (days > 0)
{
if (days <= mouths[flag][mouth + 1])
break;
else
{
days -= mouths[flag][mouth + 1];
mouth++;
} }
printf("%d\n%d",mouth+1,days);
return 0;
}
201503-1图像旋转
限时5s,还好些,看到运行1s多震惊了
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int a[1000][1000];
int main() {
int m, n;
scanf("%d %d",&n,&m);
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
scanf("%d",&a[i][j]);
}
}
for (j = m-1; j >=0; j--)
{
for (i = 0; i <n; i++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}
201503-2 数字排序
基础题
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 1010;
struct Num
{
int num;
int count;
}a[maxn];
bool cmp(Num a, Num b)
{
if (a.count != b.count) return a.count > b.count;
else return a.num < b.num;
}
int main() {
int n;
int i;
int num;
scanf("%d",&n);
for (i = 0; i < maxn; i++)
{
a[i].num = i;
a[i].count = 0;
}
for (i = 0; i < n; i++)
{
scanf("%d",&num);
a[num].count++;
}
sort(a, a + maxn,cmp);
i = 0;
while (a[i].count != 0)
{
printf("%d %d\n", a[i].num, a[i].count);
i++;
}
return 0;
}
201412-1门禁系统
基础题
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 1010;
int a[1010] = {0};//记录最多1000位读者出现的次数
int main() {
int n, i;
int id;
scanf("%d",&n);
for (i = 0; i < n; i++)
{
scanf("%d",&id);
a[id]++;
printf("%d ",a[id]);
}
return 0;
}
201412-2 Z字形扫描
这题有两个要点:首先是在循环内的判断需要保证先判断是否等于n,再判断是否等于1;其次是在输出的时候一定要有逻辑,知道离开循环的时候循环变量的值都是多少,会不会输出下标范围以外的,或者下一次循环期望值以外的i或者j
要注意样例给的是n=4,代码里我一开始直接用j<4来判断了,这样肯定不对,如果只得10分可能是这个原因orz
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 510;
int a[510][510];
int main() {
int n, i,j;
scanf("%d",&n);
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
scanf("%d", &a[i][j]);
}
}
i = j = 1;
while (i + j <= 2 * n)
{
if (j == n) //左下
{
printf("%d ", a[i][j]);
i++;
while (i < n)
{
printf("%d ", a[i][j]);
i++;
j--;
}
continue;
}
if (i == n) //右上
{
printf("%d ", a[i][j]);
j++;
while (j < n)
{
printf("%d ", a[i][j]);
j++;
i--;
}
continue;
}
if (i == 1) //左下
{
printf("%d ", a[i][j]);
j++;
while (j > 1)
{
printf("%d ", a[i][j]);
i++;
j--;
}
continue;
}
if (j == 1)//右上
{
printf("%d ", a[i][j]);
i++;
while (i > 1)
{
printf("%d ", a[i][j]);
i--;
j++;
}
continue;
}
}
return 0;
}
201409-1 相邻数对
基础题
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 1010;
int a[maxn];
int main() {
int n, i;
int num = 0;
scanf("%d",&n);
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
sort(a,a + n);
for (i = 0; i < n-1; i++)
{
if (a[i] == a[i + 1] - 1)
num++;
}
printf("%d",num);
return 0;
}
201409-2画图
把对图中每一块的填色设为对左下角点的标价,用hashtable[10000],来存储二维的100*100个坐标
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 10010;
int hashtable[maxn] = {0};
int main() {
int n, i,j,k;
int num = 0;
int x1, y1, x2, y2;
scanf("%d",&n);
for (i = 0; i < n; i++)
{
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
x2--; y2--;
for(j=x1;j<=x2;j++)
for (k = y1; k <= y2; k++)
{
hashtable[j * 100 + k] = 1;
}
}
for (i = 0; i < maxn; i++)
{
num += hashtable[i];
}
printf("%d",num);
return 0;
}
201403-1相反数
基础题,这几年一直在考察hash啊
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 1010;
int hashtable[maxn] = {0};
int main() {
int n, i;
int num ;
scanf("%d",&n);
for (i = 0; i < n; i++)
{
scanf("%d", &num);
hashtable[abs(num)]++;
}
num = 0;//表示一共有多少对
for (i = 0; i < maxn; i++)
{
if (hashtable[i] == 2)
num++;
}
printf("%d",num);
return 0;
}
201403-2 窗口
结构体排序
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
struct Window
{
int cengci;//cengci=n说明在最上面
int id;//id表示编号
int x1;
int x2;
int y1;
int y2;
}win[12];//最多10个窗口
bool cmp(Window a, Window b)
{
return a.cengci < b.cengci;
}
int main() {
int n, m;
int i;
int tempx, tempy;
int j;
scanf("%d %d", &n, &m);
for (i = 1; i <=n; i++)
{
scanf("%d %d %d %d", &win[i].x1, &win[i].y1, &win[i].x2, &win[i].y2);
win[i].id = i;
win[i].cengci = i;//
}
int tempcengci;
int tempid;
for (i = 1; i <= m; i++)
{
tempcengci = 0;
sort(win+1, win +1+ n, cmp);//注意sort是怎么写的
scanf("%d %d",&tempx,&tempy);
for (j = n; j >=1; j--)//从cengci由大到小,即从最上面开始选
{
if (win[j].x1 <= tempx && win[j].y1 <= tempy && win[j].x2 >= tempx && win[j].y2 >= tempy)
{
printf("%d\n",win[j].id);//如果选到了,就把之前的id输出
tempcengci = win[j].cengci;
tempid = win[j].id;
win[j].cengci = n;//排在最前面
break;
}
}
if (tempcengci == 0)
{
printf("IGNORED\n");
}
else
{
for (j = n; j >= 1; j--)//从cengci由大到小,即从最上面开始选
{
if(win[j].cengci > tempcengci&&win[j].id!=tempid)
win[j].cengci--;
}
}
}
return 0;
}
201312-1 出现次数最多的数
hash表
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 10010;
int hashtable[maxn] = { 0 };
int main() {
int n;
int i;
int num;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d",&num);
hashtable[num]++;
}
int max = 0;
for (i = 0; i < maxn; i++)
{
if (hashtable[i] > hashtable[max])
max = i;
}
printf("%d",max);
return 0;
}
201312-2 ISBN号码
记得数组要取大一点,因为要包括后面的结束符\0
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int main() {
char a[15];
scanf("%s",a);
int num=0;//计算正确的识别码
int temp = 1;
for (int i = 0; i <= 10; i++)
{
if (i != 1 && i != 5)
{
num += (a[i] - '0') * temp;
temp++;
}
}
num %= 11;
if (num != 10)
{
if (num == a[12] - '0')
{
printf("Right");
}
else
{
a[12] = num + '0';
printf("%s", a);
}
}
else
{
if (a[12] == 'X')
{
printf("Right");
}
else
{
a[12] ='X';
printf("%s", a);
}
}
return 0;
}
撒花花★,°:.☆( ̄▽ ̄)/$:.°★ 。