欢迎访问此位博主的CCF认证考试题解目录https://blog.csdn.net/richenyunqi/article/details/83385502
CCF 2013-12-1 出现次数最多的数
问题分析:采用下标法,a[i]的值表示整数i出现的次数
程序说明:下标法
- 数组
#include <cstdio>
int main(){
int n,x;
scanf("%d",&n);
int a[10000]={0};//注意初始化~
for(int i=0;i<n;i++){
scanf("%d",&x);
a[x]++;
}
int max=0;
int num=0;
for(int j=0;j<10000;j++){
if(a[j]>max){
max = a[j];
num = j;
}
}
printf("%d",num);
return 0;
}
- map (一对一映射)
#include <cstdio>
#include <map>
int main(){
int n,x;
scanf("%d",&n);
std::map<int,int> m;
while(n--){
scanf("%d",&x);
m[x]++;
}
int ans,count=0;
for(std::map<int,int>::iterator it=m.begin(); it!=m.end(); it++)
if(it->second > count) {
count = it->second;
ans = it->first;
}
printf("%d",ans);
return 0;
}
CCF 2013-12-2 ISBN号码
问题分析:简单模拟
程序说明:程序关键是字符变数字的方法 ch-'0'
#include <cstdio>
int main(){
char a[14];
scanf("%s",&a);
int sum=0;
sum = sum+1*(a[0]-'0')+2*(a[2]-'0')+3*(a[3]-'0')+4*(a[4]-'0')+5*(a[6]-'0')+6*(a[7]-'0')+7*(a[8]-'0')+8*(a[9]-'0')+9*(a[10]-'0') ;
sum = sum % 11;
if(sum==10){
if('X'==a[12]) printf("Right");
else printf("%c%c%c%c%c%c%c%c%c%c%c%c%c",a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],'X');
}else{
if(sum==a[12]-'0') printf("Right");
else printf("%c%c%c%c%c%c%c%c%c%c%c%c%d",a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],sum);
}
return 0;
}
/*经验:
*1、scanf与printf不能输入输出string类型
string s;
s.resize(13); //14就错了!!!
scanf("%s",&s[0]);
printf("%s",s.c_str());
*2、char ch;然后可以让ch直接等于一个数(int),比如 2 ;
ch=ch+'0'-->ch就会真的变成字符 '2' ;
*3、 printf("%s","Right");是可以的!!
*/
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
int main(){
//法二
/*经验:
*1、scanf与printf不能输入输出string类型
string s;
s.resize(13); //14就错了!!!
scanf("%s",&s[0]);
printf("%s",s.c_str());
*2、char ch;然后可以让ch直接等于一个数(int),比如 2 ;
ch=ch+'0'-->ch就会真的变成字符 '2' ;
*3、 printf("%s","Right");是可以的!!
*/
int c=1,sum=0;
string s;
s.resize(13);//14就错了!!!
scanf("%s",&s[0]);
for(int i=0;i<s.length()-1;i++){
if(s[i]!='-'){
sum += (s[i]-'0')*c++;
}
}
sum %= 11;
char ch;
ch = sum;
if(sum==10){
if(s[12]=='X') printf("Right");
else{
s[12]='X';
printf("%s",s.c_str());
}
}else{
ch += '0';
if(s[12]==ch) printf("Right");
else{
s[12]=ch;
printf("%s",s.c_str());
}
}
return 0;
}
CCF 201609-2 火车售票
/* 2020/10/06更新:
90分的原因在于 for(int j=0;j<a[i];j++)
应改为:int x=a[i];
for(int j=0;j<x;j++)
修改原因:在我的程序中,每次输出一个座位后,a[i]是不断--的,在变小,所以 j<a[i] 这里就不对了!!!
经验教训:浪费我一下午。。。无语。。。希望以后谨慎再谨慎,思维缜密再缜密!!!
*/
/*problem:201609-2火车售票
*date:2020-10-05
*code 90分 ??? -----> 100分了
*分析:
*我一开始想用二维数组代表100个座位
* 后来看了csdn,用一维数组20,我就在想,那你怎么知道每排剩下座位数
*后来一想,买票都是按顺序的,不会跳着买的(仅本题,非现实)
*比如第一排,假设剩2个座位,一定是4号和5号座位!
*计算分析:
*i排剩a[i]个座位,start=(i+1)*5-a[i]+1=i*5+6-a[i];
*/
#include <iostream>
#include <cstdio>
using namespace std;
#include <vector>
#include <algorithm>
int main(){
// int a[20]={5};
int a[20];
for(int i=0;i<20;i++){
a[i]=5;
}
int n;
scanf("%d",&n);
int num,flag=0;
while(n--){
flag=0;
scanf("%d",&num);
//先看有没有连着的!
for(int i=0;i<20;i++){
if(a[i]>=num){
flag=1;
for(int j=0;j<num;j++){
printf("%d ",(i*5+6-a[i]));
a[i]--;
}
printf("\n");
break;
}
}
//没有的话从小开始输出
if(flag==0){
for(int i=0;i<20;i++){
if(a[i]>0){
/******************************************OMG!!原来90分是因为这里出问题了!!!******************************/
/*
改前:
for(int j=0;j<a[i];j++){}
改后:
int x=a[i];
for(int j=0;j<x;j++){}
*/
int x=a[i];
for(int j=0;j<x;j++){
printf("%d ",(i*5+6-a[i]));
a[i]--;
num--;
if(num==0)
{ printf("\n");
break;}
}
}
if(num==0) break;
}
}
}
return 0;
}
code 90分 ??????为什么??求指点!!!
分析:
我一开始想用二维数组代表100个座位。后来看了csdn,用一维数组20,我就在想,那你怎么知道每排剩下座位数
后来一想,买票都是按顺序的,不会跳着买的(仅本题,非现实)
比如第一排,假设剩2个座位,一定是4号和5号座位!
计算分析:
i 排剩a[i]个座位,start=(i+1)*5-a[i]+1=i*5+6-a[i];
/*problem:201609-2火车售票
*date:2020-10-05
*code 90分 ???
*分析:
*我一开始想用二维数组代表100个座位
* 后来看了csdn,用一维数组20,我就在想,那你怎么知道每排剩下座位数
*后来一想,买票都是按顺序的,不会跳着买的(仅本题,非现实)
*比如第一排,假设剩2个座位,一定是4号和5号座位!
*计算分析:
*i排剩a[i]个座位,start=(i+1)*5-a[i]+1=i*5+6-a[i];
*/
#include <iostream>
#include <cstdio>
using namespace std;
#include <vector>
#include <algorithm>
int main(){
// int a[20]={5};
int a[20];
for(int i=0;i<20;i++){
a[i]=5;
}
int n;
scanf("%d",&n);
int num,flag=0;
while(n--){
flag=0;
scanf("%d",&num);
//先看有没有连着的!
for(int i=0;i<20;i++){
if(a[i]>=num){
flag=1;
for(int j=0;j<num;j++){
printf("%d ",(i*5+6-a[i]));
a[i]--;
}
printf("\n");
break;
}
}
//没有的话从小开始输出
if(flag==0){
for(int i=0;i<20;i++){
if(a[i]>0){
for(int j=0;j<a[i];j++){
printf("%d ",(i*5+6-a[i]));
a[i]--;
num--;
if(num==0)
{ printf("\n");
break;}
}
}
if(num==0) break;
}
}
}
return 0;
}
这个是另外博主写的,我感觉思路一样,但不懂为什么我是90,这个是100
https://blog.csdn.net/richenyunqi/article/details/79642950
更新:我试了下,这个博主的不对呀,为什么会是100分呢?
/*problem:201609-2 火车售票
*date:2020-10-05
*code 100
*https://blog.csdn.net/richenyunqi/article/details/79642950
有问题33-34行有问题,不应该100分的!!
*/
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[20];//每排剩余座位数
for(int i=0;i<20;++i)
a[i]=5;//初始化为5
int N;
scanf("%d",&N);
while(N--){
int k;
scanf("%d",&k);//读取需要几张车票
int i=0;
while(i<20&&a[i]<k)//查找是否有剩余座位数多于k的排
++i;
if(i<20){//有,从该排起始编号开始输出k个连续递增数字
int start=i*5+6-a[i];
for(int j=0;j<k;++j)
printf("%d ",start+j);
printf("\n");
a[i]-=k;
}else{//没有,从有剩余座位的排中输出空闲座位直至输出空余座位总数为k
for(int j=0;j<20&&k>0;++j)
if(a[j]>0){
int start=j*5+6-a[j];
for(int m=0;m<min(a[j],k);++m)
printf("%d ",start+m);
k-=a[j];
a[j]=k>a[j]?0:a[j]-k;
}
printf("\n");
}
}
return 0;
}
我又仿照写了一个100分的!!!我感觉跟90分的没啥差别呀???
/*problem:201609-2火车售票
*date:2020-10-05
*code 100分 (我感觉跟那90分的没差别呀!
*/
#include <iostream>
#include <cstdio>
using namespace std;
#include <vector>
#include <algorithm>
int main(){
// int a[20]={5};
int a[20];
for(int i=0;i<20;i++){
a[i]=5;
}
int n;
scanf("%d",&n);
int num,flag=0;
while(n--){
flag=0;
scanf("%d",&num);
//先看有没有连着的!
for(int i=0;i<20;i++){
if(a[i]>=num){
flag=1;
int start=i*5+6-a[i];
for(int j=0;j<num;j++){
printf("%d ",start+j);
}
a[i]-=num;
printf("\n");
break;
}
}
//没有的话从小开始输出
if(flag==0){
for(int i=0;i<20&&num>0;i++){
if(a[i]>0){
int start=i*5+6-a[i];
int x=min(a[i],num);
for(int j=0;j<x;j++){
printf("%d ",start+j);
num--;
a[i]--;
}
}
}
printf("\n");
}
}
return 0;
}
CCF 201612-1 中间数
水题
/*problem:中间数
*date:201612-1
*code 100
*法1法2都差不多只是数组和vec的差别而已
*/
#include <iostream>
#include <cstdio>
using namespace std;
#include <vector>
#include <algorithm>
#define N 1000
int main(){
int n;
scanf("%d",&n);
/*法一********************************/
// int a[N+1]={0};
// for(int i=0;i<n;i++){
// scanf("%d",&as);
// a[as]++;
// }
// int flag=0;
// for(int i=1;i<=1000;i++){
// if(a[i] != 0){
// int left=0,right=0;
// for(int j=1;j<i;j++){
// left+=a[j];
// }
// for(int k=i+1;k<=1000;k++){
// right+=a[k];
// }
// if(left==right){
// flag = 1;
// printf("%d",i);
// break;
// }
// }
//
// }
// if(!flag) printf("%d",-1);
/*法二********************************/
int x;
vector<int> a;
for(int i=0;i<n;i++){
scanf("%d",&x);
a.push_back(x);
}
sort(a.begin(),a.end());
int flag=0;
for(int i=0;i<n;i++){
int left=0,right=0;
for(int j=0;j<i;j++){
if(a[j]<a[i]) left++;
}
for(int k=i+1;k<n;k++){
if(a[k]>a[i]) right++;
}
if(left==right){
flag = 1;
printf("%d",a[i]);
break;
}
}
if(!flag) printf("%d",-1);
return 0;
}
CCF 201612-2 工资计算
分析:水题。注意细节。别算错。
重点:计算出税后工资并存储!b数组。
/*problem:201612-2 工资计算
*date:2020-10-05
*code 100
*/
#include <iostream>
#include <cstdio>
using namespace std;
#include <vector>
#include <algorithm>
int main(){
double in,out;
scanf("%lf",&out);
double a[7]={3500,5000,8000,12500,38500,58500,83500};
// double b[7]={3500,4955,7655,11255,30755,44755,61005};
double rate[8]={1.0,0.97,0.9,0.8,0.75,0.7,0.65,0.55};
double b[7]={0};
b[0]=3500;
for(int i=1;i<7;i++){
b[i]=b[i-1]+(a[i]-a[i-1])*rate[i];
}
int i=0;
while(i<7&&out>b[i]) ++i;//i=7,代表进入等级7(i=0-7)
if(i==0){
int yy = (int)out;
printf("%d",yy);
}else{
double x = (out-b[i-1])/rate[i];
double y = x + a[i-1];
int yy = (int)y;
printf("%d",yy);
}
return 0;
}
CCF 201703-2 学生排队
没有自己做,照抄博主的博客。
/*problem:201703-2 学生排队
*date:2020-10-06
*code
复制粘帖博主的博客 100分
*/
#include <iostream>
#include <cstdio>
#include <list>
using namespace std;
int main(){
int N,M;
scanf("%d%d",&N,&M);
list<int>l;//存储学号的链表
for(int i=0;i<N;++i)//将所有学号加入链表中
l.push_back(i+1);
while(M--){
int a,b;
scanf("%d%d",&a,&b);//读取移动的学号,和移动的长度
list<int>::iterator i=l.begin();
while(*i!=a)//遍历链表查找要移动的学号在链表中的位置
++i;
i=l.erase(i);//删除该元素
while(b<0){//找到移动后的位置
--i;
++b;
}
while(b>0){
++i;
--b;
}
l.insert(i,a);//插入该元素
}
for(list<int>::iterator i=l.begin();i!=l.end();++i)//遍历输出
printf("%d ",*i);
return 0;
}
CCF 201709-2 公共钥匙盒
(1次通过)
分析:
先看还钥匙再看取钥匙;
还钥匙遵循2个原则:先把要还的钥匙编号升序排好,再把钥匙从左往右找空位还回去。
/*problem:201709-2 公共钥匙盒
*date:2020-10-06
*code 100分(1次通过
分析:
先看还钥匙再看取钥匙;
还钥匙遵循2个原则:先把要还的钥匙编号升序排好,再把钥匙从左往右找空位还回去。
*/
/*
每次取钥匙的时候,老师们都会找到自己所需要的钥匙将其取走,而不会移动其他钥匙。
-每次还钥匙的时候,还钥匙的老师会找到最左边的空的挂钩,将钥匙挂在这个挂钩上。
-如果有多位老师还钥匙,则他们按钥匙编号从小到大的顺序还。
-如果同一时刻既有老师还钥匙又有老师取钥匙,则老师们会先将钥匙全还回去再取出。
*/
#include <iostream>
#include <cstdio>
using namespace std;
#include <algorithm>
#include <vector>
int main(){
int N,K;
scanf("%d%d",&N,&K);//N把钥匙,K位老师
int loc[N];//0~N-1的顺序位置,分别存放的几号钥匙。loc[i]=0代表该位置为空。
for(int i=0;i<N;i++){
loc[i]=i+1;
}
int maxtime=0;//最晚还钥匙的时间
int t[K][4];//(老师)0钥匙编号-1拿钥匙时间-2上课时常-3放回钥匙时间
for(int i=0;i<K;i++){
scanf("%d%d%d",&t[i][0],&t[i][1],&t[i][2]);
t[i][3]=t[i][2]+t[i][1];
if(t[i][3]>maxtime) maxtime=t[i][3];
}
vector<int> v;
/*对每个单位时刻,查看还钥匙(1、钥匙编号从小到大还 2、挂钩位置从左到右挂)和取钥匙的情况。*/
for(int i=1;i<=maxtime;i++){
/*1、还钥匙*/
for(int j=0;j<K;j++){//对每位老师
if(t[j][3]==i){//还钥匙时间是否是当下时刻i
v.push_back(t[j][0]);
}
}
sort(v.begin(),v.end());//要还钥匙的编号排序
int index=0;
for(int j=0;j<N&&index<v.size();j++){//还钥匙
if(loc[j]==0){
loc[j]=v[index];
index++;
}
}
v.clear();
/*2、取钥匙*/
for(int j=0;j<K;j++){//对每位老师
if(t[j][1]==i){//取钥匙时间是否是当下时刻i
for(int k=0;k<N;k++){//qu钥匙
if(loc[k]==t[j][0]){
loc[k]=0;
break;
}
}
}
}
}
for(int k=0;k<N;k++){
printf("%d ",loc[k]);
}
return 0;
}
CCF 201712-2 游戏
2020.10.6:仍然不知道为什么我的答案0分,当然我承认循环队列太方便了,只是我还是想知道我的样例通过了,为啥是0分
/*problem:201712-2 游戏
*date:2020-10-06
*code 0分 ???
*/
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
int n,k;
scanf("%d%d",&n,&k);
int child[n];
for(int i=0;i<n;i++) child[i] = i+1;
int num=n,count=0,x=0;//剩下孩子数目,数数12345678..., child下角标
while(num!=1){//num=1时,代表只剩下child[0]一个孩子
count++;
//当前的child[x],知道x是几?
if(count%k==0||count%10==k){//应该把当前孩子删掉。 后面的孩子前挪。
if(x==num-1){//error!刚开始落下这个if.
child[x]=0;
x=0;
num--;
}else{
for(int i=x;i<num-1;i++) child[x]=child[x+1];
child[num-1]=0;
num--;
}
} else{//不必删掉当前孩子,num也不变,只是x要指向下一个孩子了。
if(x==num-1){
x=0;
} else{
x++;
}
}
}
printf("%d",child[0]);
return 0;
}
/*problem:201712-2 游戏
*date:2020-10-06
*code 100分
不得不说队列可太方便了!!!
*/
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
int main(){
int n,k;
scanf("%d%d",&n,&k);
queue<int> q;
for(int i=0;i<n;i++) q.push(i+1);
int count=1;
while(q.size()>1){
if(count%k==0||count%10==k){
q.pop();
}else{
int x = q.front();
q.pop();
q.push(x);
}
++count;
}
printf("%d",q.front());
return 0;
}
CCF 201803-2 碰撞的小球
还是主观臆断造成的。。。
/*problem:201803-2
*date:2020-10-06
*code 10-->100
错误原因:误以为输入的小球位置按从小到大顺序输入的,导致在 “2球碰撞 -改变方向”这个程序内我只关注loc[j]和loc[j+1],而没有关注任意2个球是否会碰撞。
*/
/*开始时所有的小球都处在偶数坐标上,速度方向向右,速度大小为1单位长度每秒*/
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
int n,L,t;
scanf("%d%d%d",&n,&L,&t);
int loc[n]={0};
int dir[n]={0};
for(int i=0;i<n;i++){
scanf("%d",&loc[i]);
dir[i]=1;//1代表刚开始速度方向都是朝右。 -1代表朝左。
}
for(int i=0;i<t;i++){//对于每1秒。
for(int j=0;j<n;j++){//对于每个球+1 or -1;
loc[j]+=dir[j];
}
for(int j=0;j<n;j++){//对于每个球判断下一次会不会碰撞,若碰撞则速度方向*(-1)
if((loc[j]==0)or(loc[j]==L)){//球碰墙-改变方向
dir[j]*=(-1);
}
for(int k=j+1;k<n;k++){
if(loc[j]==loc[k]){//2球碰撞 -改变方向
dir[j]*=(-1);
dir[k]*=(-1);
}
}
}
}
for(int i=0;i<n;i++){
printf("%d ",loc[i]);
}
return 0;
}
CCF 201809-2 买菜
分析:搞清逻辑,分类别重复!
/*problem:201809-2 买菜
*date:2020-10-06
*code 100 一次通过
关键是分好类,逻辑搞清楚!!!
*/
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
long long n,a,b,c,d;
scanf("%lld",&n);
long long h[n][2];
long long w[n][2];
for(int i=0;i<n;i++){
scanf("%lld%lld",&a,&b);
h[i][0]=a;
h[i][1]=b;
}
for(int i=0;i<n;i++){
scanf("%lld%lld",&c,&d);
w[i][0]=c;
w[i][1]=d;
}
long long sum=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(h[i][0]<w[j][0]&&w[j][0]<h[i][1]&&h[i][1]<w[j][1]) sum+=(h[i][1]-w[j][0]);
if(w[j][0]<h[i][0]&&h[i][0]<w[j][1]&&w[j][1]<h[i][1]) sum+=(w[j][1]-h[i][0]);
if(h[i][0]<=w[j][0]&&w[j][1]<=h[i][1]) sum+=(w[j][1]-w[j][0]);
if((w[j][0]<h[i][0]&&h[i][1]<w[j][1])or(w[j][0]<=h[i][0]&&h[i][1]<w[j][1])or(w[j][0]<h[i][0]&&h[i][1]<=w[j][1])) sum+=(h[i][1]-h[i][0]);
}
}
printf("%lld",sum);
return 0;
}
CCF 201812-2 小明放学
分析:黄红绿的顺序,y,r,g;
num-从出发时刻到当前时刻,经历了多少秒。
temp-对某个红绿灯来说,经过num秒后,该灯处于(0 ~ y+r+g) 这个区间的哪里?
(1)处于(0~y+r)区间,就需要等待
(2)处于(y+r~y+r+g)区间就不需要等待。(y+r+g除外,因为经过mod运算,y+r+g%ryg=0会归为第一类!!!
经验:刚开始20分的原因是因为交通规则我都忘了,我人傻了;
1、亮灯顺序不是题目123对应的红黄绿,而是黄红绿!!!(主观臆断了,害~
2、黄灯停!!!警告红灯要来了,所以也不能走!!!
3、就是数据类型了,int可能会溢出,所以用long long
/*problem:201812-2 小明放学
*date:2020-10-06
*code
*开始直接认为:红-黄-绿; 1-2-3(题目的序号
后来:红-绿-黄; 我傻了~
后来:黄灯不能走啊原来;我傻了~
*/
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
long long r,y,g;
scanf("%lld%lld%lld",&r,&y,&g);
long long ryg=r+y+g;
long long n,k,t;
scanf("%lld",&n);
long long num=0,temp=0;
while(n--){
scanf("%lld%lld",&k,&t);
if(k==0) {
num+=t;
// printf("%d\n",t);
}
if(k==1){
temp = (y+r-t+num)%ryg;
if(temp>=0&&temp<=y+r){
num+=y+r-temp;
// printf("%d\n",r-temp);
}
}else if(k==2){
temp = (y-t+num)%ryg;
if(temp>=0&&temp<=y+r){
num+=y+r-temp;
// printf("%d\n",r-temp);
}
}else if(k==3){
temp = (y+r+g-t+num)%ryg;
if(temp>=0&&temp<=y+r){
num+=y+r-temp;
// printf("%d\n",r-temp);
}
}
}
printf("%lld",num);
return 0;
}
CCF 201903-2 二十四点
问题分析:表达式计算问题,关键是对输入流进行处理,需要考虑表达式中运算符的优先级。
程序说明:我参考了STL(栈),
比如 c[8] = '2-3-4*5',逐个读取这个表达式c[i],
2入栈;遇到‘-’,那么'0'-c[++i]入栈,也就是-3入栈;然后-4入栈;然后遇到x号,让-4*5=-20入栈(记得先让-4出栈);
这时栈里面依次是:2、-3、-20,然后把栈内的数想加即可。
/*problem:二十四点
*date:2020/10/04
*STL(栈)
*/
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
int main(){
int n;
scanf("%d",&n);
while(n--){
char c[8];
scanf("%s",&c);
int sum = 0;
stack<int> mystack;
for(int i=0;i<7;i++){
if(c[i]>='1'&&c[i]<='9'){
mystack.push(c[i]-'0');
}else if(c[i]=='+'){
mystack.push(c[++i]-'0');
}else if(c[i]=='-'){
mystack.push('0'-c[++i]);
}else if(c[i]=='x'){
sum = mystack.top()*(c[++i]-'0');
mystack.pop();
mystack.push(sum);
sum = 0;
}else if(c[i]=='/'){
sum = mystack.top()/(c[++i]-'0');
mystack.pop();
mystack.push(sum);
sum = 0;
}
}
while(!mystack.empty()){
sum+=mystack.top();
mystack.pop();
}
if(sum==24) printf("Yes\n");
else printf("No\n");
}
return 0;
}
CCF 201909-1 小明种苹果
水题,注意输出时的空格
/*problem:小明种苹果
*date:201909-1
*code 100
*/
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
int n,m;
scanf("%d%d",&n,&m);
int t=0,k=1,p=0;
int tnum,shu,shup=0;
for(int i=1;i<=n;i++){//n棵树
scanf("%d",&tnum);
t+=tnum;
for(int j=1;j<=m;j++){
scanf("%d",&shu);
shup-=shu;
}
t-=shup;
if(shup>p){
p=shup;
k=i;
}
shup=0;
}
printf("%d %d %d",t,k,p);
return 0;
}
CCF 201909-2 小明种苹果(续
水题
我有两个错误原因,在代码中已经标出:
(1)注意输入的是正负数?所以对应加还是减?
(2) 5个数,0-4这样可以循环轮回,比如3+1应4,结果3+1/5=4--正确
1-5就不可以循环轮回了,比如4+1本应5,结果4+1/5=0.--错误
/*problem:小明种苹果 (续
*date:201909-2
*code 70 -> 100
*/
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
int main(){
map<int,int> luo;//n棵树,对应自身是否落果。
int n,m,ms,mm;
scanf("%d",&n);
int sum=0,nownum=0;//记录每棵树剩下的果子的和,当下还剩多少果子。
for(int i=1;i<=n;i++){//对于n棵树的每一棵树
scanf("%d%d",&m,&ms);//当前这棵树有m个整数,以及第一次果子数。
nownum=ms;
for(int j=1;j<m;j++){
scanf("%d",&mm);
if(mm>0){
if(nownum>mm) {
luo[i]=1;
nownum=mm;
}
}else{
nownum+=mm;//错误1:开始写成+了,忘记mm是负数了!
}
}
sum+=nownum;
}
int d=0,e=0;
for(int i=1;i<=n;i++){
//错误2:开始是从i=1,应该从i=0开始,才能让3+1/5 = 4,还是第五个数[4]本身
//否则, i=1开始的话,是4+1/5=0,就不是第五个数[5]本身了。
if(luo[i]) d++;
if(luo[i]&&luo[(i+1)%n]&&luo[(i+2)%n]) e++;
}
printf("%d %d %d",sum,d,e);
return 0;
}
CCF 201912-2 回收站选址
/*problem:201912-2 回收站选址
*date:2020-10-06
*code 100 一次通过,真不容易~~
经验:在C++中如何将二维数组作为函数参数? https://blog.csdn.net/ytzlln/article/details/78220226
*/
#include <iostream>
#include <cstdio>
using namespace std;
#define N 1000
int countFour(int n,int a[][2],int x,int y){//上下左右四个位置存在垃圾的个数?
int num=0;
for(int j=0;j<n;j++){
if((a[j][0]==x&&a[j][1]==(y+1))or(a[j][0]==x&&a[j][1]==(y-1))or(a[j][0]==(x+1)&&a[j][1]==y)or(a[j][0]==(x-1)&&a[j][1]==y)) num++;
}
return num;
}
int countGrade(int n,int a[][2],int x,int y){//左上左下右上右下四个角存在垃圾的个数?
int num=0;
for(int j=0;j<n;j++){
if((a[j][0]==(x+1)&&a[j][1]==(y+1))or(a[j][0]==(x+1)&&a[j][1]==(y-1))or(a[j][0]==(x-1)&&a[j][1]==(y+1))or(a[j][0]==(x-1)&&a[j][1]==(y-1))) num++;
}
return num;
}
int main(){
int n,x,y;
scanf("%d",&n);
int a[n][2];
for(int i=0;i<n;i++){
scanf("%d%d",&x,&y);
a[i][0]=x;
a[i][1]=y;
// a[i][2]=0;
}
int b[5]={0};
for(int i=0;i<n;i++){
x = a[i][0];
y = a[i][1];
if(countFour(n,a,x,y)==4){//代表可以作为回收站了!才可以评分!
// a[i][2]=1;//1--代表可以评分!
b[countGrade(n,a,x,y)]++;
}
}
for(int i=0;i<5;i++){
printf("%d\n",b[i]);
}
return 0;
}
CCF 202006-1 线性分类器
问题分析:看输入的直线能否把A类和B类分离开。
程序说明:我只用一个a[N]数组存储三元点;而好多博主用了两个一个存储A类点一个存储B类点。感觉2个更方便!以后试试
经验:确实水题,可我愣是在输入A和B上出了问题:
我写的是char type; 然后输入一个字符A or B,没想到循环输入的时候一直出错,2次循环只输入了1次,5次循环只能输入3次。
后来我发现好像是scanf("%c",&type)还能接受我的‘Enter’键换行符~~~,所以每一次输入一个字符A事实上输入了两次字符。
改成:char type[2]; 和 scanf("%s",&type)就可以了!!!![我做了俩小时~~15-17点~~惨~~]
/*problem:线性分类器
*date:202006-1
*/
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
#define N 1000
struct point{
int x;
int y;
char type[2];
bool flag;
}a[N];
bool judge(int n){
int flag1=-1,flag2=-1;//A类点小于0,flag1=0;A类点大于0,flag1=1;
int numa=0,numb=0;//记录A与B的数量,其实主要是记录第一个 A与B 而已。
for(int i=0;i<n;i++){
if(a[i].type[0]=='A'){
numa++;
if(flag1==-1){
if(numa==1) {flag1=a[i].flag;flag2=!a[i].flag;}
else if(a[i].flag!=flag1) return false;
}else{
if(a[i].flag!=flag1) return false;
}
}else{
numb++;
if(flag2==-1) {
if(numb==1) {flag2=a[i].flag;flag1=!a[i].flag;}
else if(a[i].flag!=flag2) return false;
}else{
if(a[i].flag!=flag2) return false;
}
}
}
return true;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
int x,y;
char type[2];
for(int i=0;i<n;i++){
scanf("%d%d%s",&x,&y,&type);
a[i].x=x;
a[i].y=y;
a[i].type[0]=type[0];
}
int o1,o2,o3;
while(m--){
//判断每一个直线能不能作为分类器Y or N(共m个直线)
scanf("%d%d%d",&o1,&o2,&o3);
for(int i=0;i<n;i++){
if(o1+o2*a[i].x+o3*a[i].y > 0) a[i].flag=1;
else a[i].flag =0;
}
printf(judge(n)? "Yes\n":"No\n");
}
return 0;
}
CCF 202006-2 稀疏向量
问题分析:内积
程序说明:略
明明很简单为啥60分!!!!
另一位60分的博主,我觉得我可能是因为定义的数组?
(一开始用了n+1大小的数组打算直接暴力解,然后用了a+b大小的结构体数组想着缩小数据大小应该能过,结果都卡在60分运行错误。
接着使用了vector容器直接输入a+b个数据然后排序来求解,结果是30分运行超时。
运行错误可能是由于a+b大小不确定导致当a+b较大时,无法直接按照这样定义数组。
运行超时我觉得也是一样的原因,即使使用sort排序也还是会时间过长。
(照着AC代码跑才刚好2s))
/*problem:稀疏向量
*date:202006-2
*code 60分
*/
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
long long n,a,b;
scanf("%lld%lld%lld",&n,&a,&b);
long long u[n+1]={0};
long long index,value,sum=0;
while(a--){
scanf("%lld%lld",&index,&value);
u[index]=value;
}
while(b--){
scanf("%lld%lld",&index,&value);
sum+=u[index]*value;
}
printf("%lld",sum);
return 0;
}
我将数组改成map映射就通过了!!真奇怪!! 其实我好奇,假设map[5]没有定义,会存储什么【我试了,竟然是0 !】
/*problem:稀疏向量
*date:202006-2
*code 100分
*/
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
int main(){
int n,a,b;
scanf("%d%d%d",&n,&a,&b);
map<int,int> mymap;
int index,value;
long long sum=0;
while(a--){
scanf("%d%d",&index,&value);
mymap[index]=value;
}
while(b--){
scanf("%d%d",&index,&value);
sum+=mymap[index]*value;
}
printf("%lld",sum);
return 0;
}