CCF练习题目(二)

接上一节:CCF练习题目(一)

1006: 日历问题

题目描述

在 我们现在使用的日历中, 闰年被定义为能被4整除的年份,但是能被100整除而不能被400整除的年是例外,它们不是闰年。例如:1700, 1800, 1900 和 2100 不是闰年,而 1600, 2000 和 2400是闰年。 给定从公元2000年1月1日开始逝去的天数,你的任务是给出这一天是哪年哪月哪日星期几。

输入

输入包含若干行,每行包含一个正整数,表示从2000年1月1日开始逝去的天数。输入最后一行是−1, 不必处理。可以假设结果的年份不会超过9999。

输出

对 每个测试样例,输出一行,该行包含对应的日期和星期几。格式为“YYYY-MM-DD DayOfWeek”, 其中 “DayOfWeek” 必须是下面中的一个: "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" and "Saturday“。

样例输入

1730

1740

1750

1751

-1

样例输出

2004-09-26 Sunday

2004-10-06 Wednesday

2004-10-16 Saturday

2004-10-17 Sunday

#include<iostream>
using namespace std;

bool p(int year){
	if((year%4==0&&year%100!=0)||year%400==0){
		return 1;
	}
	else{
		return 0;
	}
}

int main(){
	int n;
	int a[12]={31,29,31,30,31,30,31,31,30,31,30,31};
	int b[12]={31,28,31,30,31,30,31,31,30,31,30,31};


	while(cin>>n&&n>0){
		int all=n;
		int year=2000;
		int month;
		int day;
		int y;
	    n++;
		while(n>366){
			if((year%4==0&&year%100!=0)||year%400==0){
				n-=366;
				year++;
			}
			else{
				n-=365;
				year++;
			}
		}
		
		int i=0;
		int j=0;
		if(p(year)==1){
			while(n>0){
				n-=a[i];
				i++;	
			}
			  month=i;
			  day=n+a[i-1];
		}

		else{
			if(n==366){
				year++;
				month=1;
				day=1;
			}
			else{
				while(n>0){
				n-=b[j];
				j++;
			}	
		    month=j;
            day=n+b[j-1];
			}
		
		}
    	
        y=all%7;
        string c;
        switch(y){
        	case 0:c="Saturday";break;
        	case 1:c="Sunday";break;
        	case 2:c="Monday";break;
        	case 3:c="Tuesday";break;
        	case 4:c="Wednesday";break;
        	case 5:c="Thursday";break;
        	case 6:c="Friday";break;
        }
        
      if(month<10){
      	if(day<10){
      		cout<<year<<"-"<<"0"<<month<<"-"<<"0"<<day<<" "<<c<<endl;	
      	}
      	else{
      		cout<<year<<"-"<<"0"<<month<<"-"<<day<<" "<<c<<endl;	
      	}
      }
      
      else{
      	    if(day<10){
      		cout<<year<<"-"<<month<<"-"<<"0"<<day<<" "<<c<<endl;	
      	}
      	else{
      		cout<<year<<"-"<<month<<"-"<<day<<" "<<c<<endl;	
      	}
      }
     }   
	
	return 0;
}

1007: 生理周期 

题目描述

人 生来就有三个生理周期,分别为体力、感情和智力周期,它们的周期长度为23 天、 28 天和33 天。每一个周期中有一天是高峰。在高峰这天,人会在相应的方面表现出色。例如,智力周期的高峰,人会思维敏捷,精力容易高度集中。因为三个周期的周长不 同,所以通常三个周期的高峰不会落在同一天。对于每个人,我们想知道何时三个高峰落在同一天。对于每个周期,我们会给出从当前年份的第一天开始,到出现高 峰的天数(不一定是第一次高峰出现的时间)。你的任务是给定一个从当年第一天开始数的天数,输出从给定时间开始(不包括给定时间)下一次三个高峰落在同一 天的时间(距给定时间的天数)。例如:给定时间为10,下次出现三个高峰同天的时间是12,则输出2(注意这里不是3)。

输入

输入四个整数:p, e, i 和d。 p, e, i 分别表示体力、情感和智力高峰出现的时间(时间从当年的第一天开始计算)。d 是给定的时间,可能小于p, e, 或 i。 所有给定时间是非负的并且小于365, 所求的时间小于等于21252。

输出

从给定时间起,下一次三个高峰同天的时间(距离给定时间的天数)。

样例输入

0 0 0 0

0 0 0 100

5 20 34 325

4 5 6 7

283 102 23 320

203 301 203 40

-1 -1 -1 -1

样例输出

Case 1: the next triple peak occurs in 21252 days.

Case 2: the next triple peak occurs in 21152 days.

Case 3: the next triple peak occurs in 19575 days.

Case 4: the next triple peak occurs in 16994 days.

Case 5: the next triple peak occurs in 8910 days.

Case 6: the next triple peak occurs in 10789 days.

#include<iostream>
using namespace std;

int main(){
	int p,e,i,d;
	int num=0;
	while(cin>>p>>e>>i>>d&&p>=0&&e>=0&&i>=0&&d>=0){
		num++;
		for(int k=1;k<=28*33;k++){
			double a,b;
			int sum=0;
			a=((p+23*k)-e)%28;
			b=((p+23*k)-i)%33;
			if(a==0&&b==0){
				sum=p+23*k-d;
				cout<<"Case "<<num<<": the next triple peak occurs in "<<sum<<" days."<<endl;
				break;
			}
		}
	}
	return 0;
}

1008: 约瑟夫问题 

题目描述

约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1 开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入

每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m, n < 300)。最后一行是: 0 0

输出

对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号

样例输入

6 2

12 4

8 3

0 0

样例输出

5

1

7

 

#include<iostream>
using namespace std;

int main(){
	int n,m;
	int num[300]={0};
	int mcount,ncount;
	while(cin>>n>>m&&n>0&&m>0){
		for(int i=0;i<n;i++){
			num[i]=1;
	}			
		ncount=n;
		mcount=0;
		while(ncount>1){
			for(int i=0;i<n;i++)
				if(num[i]==1){
					mcount++;
					if(mcount%m==0){
						num[i]=0;
						ncount--;
					}
				}
		}
		for(int i=0;i<n;i++){
			if(num[i]==1){
				cout<<i+1<<endl;
			}
		}
	}
	return 0;
}

1009: 恺撒Caesar密码 

题目描述

Julius Caesar 生活在充满危险和阴谋的年代。为了生存,他首次发明了密码,用于军队的消息传递。假设你是Caesar 军团中的一名军官,需要把Caesar 发送的消息破译出来、并提供给你的将军。消息加密的办法是:对消息原文中的每个字母,分别用该字母之后的第5个字母替换(例如:消息原文中的每个字母A都 分别替换成字母F),其他字符不 变,并且消息原文的所有字母都是大写的。 密码字母:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 原文字母:V W X Y Z A B C D E F G H I J K L M N O P Q R S T U

输入

最多不超过100个数据集组成。每个数据集由3部分组成:起始行:START 密码消息:由1到200个字符组成一行,表示Caesar发出的一条消息结束行:END 在最后一个数据集之后,是另一行:ENDOFINPUT

输出

每个数据集对应一行,是Caesar 的原始消息。

样例输入

START

NS BFW, JAJSYX TK NRUTWYFSHJ FWJ YMJ WJXZQY TK YWNANFQ HFZXJX

END

START

N BTZQI WFYMJW GJ KNWXY NS F QNYYQJ NGJWNFS ANQQFLJ YMFS XJHTSI NS WTRJ

END

START

IFSLJW PSTBX KZQQ BJQQ YMFY HFJXFW NX RTWJ IFSLJWTZX YMFS MJ

END

ENDOFINPUT

样例输出

IN WAR, EVENTS OF IMPORTANCE ARE THE RESULT OF TRIVIAL CAUSES

I WOULD RATHER BE FIRST IN A LITTLE IBERIAN VILLAGE THAN SECOND IN ROME

DANGER KNOWS FULL WELL THAT CAESAR IS MORE DANGEROUS THAN HE

 

#include<iostream>
using namespace std;

int main(){
	string a,n,b;
	char x[26]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
	char y[26]={'V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U'};
	while(getline(cin,a)&&getline(cin,n)&&getline(cin,b)){
		if(a=="START"&&b=="END"){
			for(int i=0;n[i]!='\0';i++){
				if(n[i]>='A'&&n[i]<='Z'){
					for(int j=0;j<26;j++){
						if(n[i]==x[j]){
							cout<<y[j];
						}
					}
				}
				else{
					cout<<n[i];
				}
			}
			cout<<endl;
		}
		else{
			break;
		}
	}
	return 0;
}

1010: 身份证校验 

题目描述

我国国标〖GB 11643-1999〗中规定:公民身份号码是18位特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。其校验码(最后一位)计算方法和步骤为:

(1)十七位数字本体码加权求和公式

S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和

其中Ai:表示第i位置上的身份证号码数字值

Wi:表示第i位置上的加权因子,前17位加权因子从左到右分别为

Wi:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

(2)计算模

Y = mod(S, 11)

(3)通过模Y查下表得到对应的校验码

Y

0

1

2

3

4

5

6

7

8

9

10

校验码

1

0

X

9

8

7

6

5

4

3

2

例如:某身份证前17位为11010519491231002

i

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

wi

7

9

10

5

8

4

2

1

6

3

7

9

10

5

8

4

2

 

1

1

0

1

0

5

1

9

4

9

1

2

3

1

0

0

2

7

9

0

5

0

20

2

9

24

27

7

18

30

5

0

0

4

得到和为:167;则模为y=167%11=2

查(3)得校验码为X(大写)

请按上面所述步骤编程,输入一个二代身份证号,检查该身份证是否正确。

输入

输入若干行,每行一个身份证号码,最后一行输入-1

输出

输出1代表正确,0代表错误

样例输入

120223198902021249

130132199210293822

130402198207290622

-1

样例输出

1

1

0

#include<iostream>
using namespace std;

int main(){
	int wi[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
	string n;
	int ai[18];
	while(cin>>n&&n!="-1"){
		int sum=0;
		int y;
		char b;
		for(int i=0;i<18;i++){
			ai[i]=n[i]-'0';
		}
		for(int i=0;i<17;i++){
			sum+=ai[i]*wi[i];
		}
		y=sum%11;
		switch(y){
			case 0:b='1';break;
			case 1:b='0';break;
			case 2:b='X';break;
			case 3:b='9';break;
			case 4:b='8';break;
			case 5:b='7';break;
			case 6:b='6';break;
			case 7:b='5';break;
			case 8:b='4';break;
			case 9:b='3';break;
			case 10:b='2';break;
		}
		if(b==n[17]){
			cout<<"1"<<endl;
		}
		else{
			cout<<"0"<<endl;
		}
	}
	return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值