CCF历年题目

欢迎访问此位博主的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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值