PAT乙级

PAT乙级1007-

  • cin、cout花费时间久,>1000时容易超时

A除以B

本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数。你需要输出商数Q和余数R,使得A = B * Q + R成立。
输入描述:
输入在1行中依次给出A和B,中间以1空格分隔。
输出描述:
在1行中依次输出Q和R,中间以1空格分隔。

  • 学会使用字符串,模拟用笔计算
#include<iostream> 
using namespace std;
int main(){
	string A;
	int B,R=0;
	int m,n=0;
	cin>>A>>B;
	char Q;
	for(int i=0;i<A.length();i++){
		m=R*10+(A[i]-'0');
		Q=m/B+'0';
		R=m%B;
	
		if(i==0&&Q=='0'){
			continue;
		}
		else{
			cout<<Q;
		}
	}
	cout<<' '<<R<<endl;
	return 0;
}

锤子剪刀布

输入描述:
输入第1行给出正整数N(<=105),即双方交锋的次数。随后N行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C代表“锤子”、J代表“剪刀”、B代
表“布”,第1个字母代表甲方,第2个代表乙方,中间有1个空格。
输出描述:
输出第1、2行分别给出甲、乙的胜、平、负次数,数字间以1个空格分隔。第3行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有1个空格。如果解不唯一,则输出按字母序最小的解。

  • 一位数组初始化为的方法
    • .int arr[10]={0};
    • int arr[31]={};
    • int arr[1024]; memset(arr, 0, 1024); //清零
#include<iostream>
#include<cstdio>
using namespace std;
char cmp(int *K){
	if(K[0]<K[1]){
		if(K[1]<=K[2]){
			return 'B';
		}
		else return 'J';
	}
	else{
		if(K[0]<=K[2]){
			return 'B';
		}
		else
			return 'C';
	}
}
int main(){
	int n;
	cin>>n;
	char a,b;
	int p[3]={0};
	int q[3]={0}; 
	int win1[3]={0};
	int win2[3]={0};
	
	for(int i=0;i<n;i++){
		cin>>a>>b;		
		if(a==b){
			p[1]++;
			q[1]++;
		}
		else if(a=='C'){
			
			if(b=='J'){
				win1[0]++;
				p[0]++;
				q[2]++;
			}
			else{
				win2[2]++;
				p[2]++;
				q[0]++;
			}
			
		}
		else if(a=='J'){
			if(b=='C'){
				win2[0]++;
				p[2]++;
				q[0]++;
			}
			else{
				win1[1]++;
				p[0]++;
				q[2]++;
			}
		}
		else if(a=='B'){
			if(b=='C'){
				win1[2]++;
				p[0]++;
				q[2]++;
			}
			else{
				win2[1]++;
				p[2]++;
				q[0]++;
			}
		}
	}
	
	cout<<p[0]<<' '<<p[1]<<' '<<p[2]<<'\n';
	cout<<q[0]<<' '<<q[1]<<' '<<q[2]<<'\n';
	cout<<cmp(win1)<<' '<<cmp(win2);
	
	
	return 0;
}

数字黑洞

给定任一个各位数字不完全相同的4位正整数,如果我们先把4个数字按非递增排序,再按非递减排序,然后用第1个数字减第2个数字,将得到
一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的6174,这个神奇的数字也叫Kaprekar常数。

例如,我们从6767开始,将得到

7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
… …

现给定任意4位正整数,请编写程序演示到达黑洞的过程。

  • 自己的麻烦算法超时了!!
  • changeNum(),数组转化为数字
  • changeChar(),数字转化为数组 ,虽然顺序发生改变,但本题不影响计算
  • printf("%04d") 右对齐,左边填充0
#include<iostream>
#include<string>
#include<algorithm> 
#include<cstdio>
using namespace std;

bool cmp(char a,char b){
	return a>b;//转为降序 
}

int changeNum(int s[]){
	int n=0;
	for(int i=0;i<4;i++){
		n=n*10+s[i];
	}
	return n;
}

void changeChar(int n,int s[]){//数组的转出! 
	for(int i=0;i<4;i++){//!!! 
		s[i]=n%10;
		n=n/10;
	} 
	
}


int main(){
	int s[4];
	int n;
	cin>>n;
	int a,b;
	while(n!=0){
		changeChar(n,s);
		sort(s,s+4,cmp);//降序7766 
		a=changeNum(s);
		sort(s,s+4);//6677
		b=changeNum(s);
		n=a-b;//0000 6174
		printf("%04d - %04d = %04d\n",a,b,n);
		if(n==0||n==6174){
			break;
		}	
	}
	
	return 0;
}  

D进制的A+B

输入两个非负10进制整数A和B(<=230-1),输出A+B的D (1 < D <= 10)进制数。

  • 学学这个简短的模拟手算的递归吧!
#include<iostream>
using namespace std;

void change(int num,int D){
	if(num/D){
		change(num/D,D);
	}
	cout<<num%D;
} 
int main(){
	int A,B;
	cin>>A>>B;
	int D;
	cin>>D;
	change(A+B,D); 
	
	return 0;
}

组个最小数

给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)。例如:
给定两个0,两个1,三个5,一个8,我们得到的最小的数就是10015558。

现给定数字,请编写程序输出能够组成的最小的数。
每个输入包含1个测试用例。每个测试用例在一行中给出10个非负整数,顺序表示我们拥有数字0、数字1、……数字9的个数。整数间用一个空
格分隔。10个数字的总个数不超过50,且至少拥有1个非0的数字。

  • 简洁明了,第一个for输入,第二个for输出最小的,并把相应计数-1,第三行输出剩余
#include<iostream>
using namespace std;
int main() {
    int count[10];
    for(int i = 0; i < 10; i++)
        cin >> count[i];
    for(int i = 1; i < 10; i++)
        if(count[i]) {
            cout << i;
            count[i]--;
            break;
        }
    for(int i = 0; i < 10; i++)
        while(count[i]--)
            cout << i;
    return 0;
}

科学计数法

  • string的用法
#include<iostream>
#include<vector> 
#include<string>
#include<cmath>
using namespace std;

int main(){
	string s,ans;
	cin>>s;
	if(s[0]=='-'){
		cout<<'-';
	}
	int k=s.find('E');//s.find()返回E所在下标 
	int z,exp=0;
	for(int i=k+2;i<s.length();i++){
		z=s.length()-i-1;//s.length(),返回的是长度 
		exp+=(s[i]-'0')*pow(10,z);
	}
//	cout<<exp<<'\n'; 移动位数 
	int m=k-3;
	if(s[k+1]=='+'){//小数点右移 
		
		if(m>exp){
			s.erase(2,1);//删除从2开始1位 
			s.insert(2+exp,"."); //插入 
			ans=s.substr(1,m+2);
			cout<<ans;
		} 
		else if(m==exp){
			s.erase(2,1);//删除从2开始1位 
			ans=s.substr(1,m+1);
			cout<<ans;
		}
		else{
			int n=exp-m;
			s.erase(2,1);
			ans=s.substr(1,m+1);
			cout<<ans;
			for(int i=0;i<n;i++){
				cout<<'0';
			}
		}
	}
	else{//-
		s.erase(2,1);
		ans=s.substr(1,m+1);
		cout<<"0.";
		for(int i=0;i<exp-1;i++){
			cout<<'0';
		}
		cout<<ans; 
		
	}
	
	return 0;
} 

程序运行时间

题目描述

要获得一个C语言程序的运行时间,常用的方法是调用头文件time.h,其中提供了clock()函数,可以捕捉从程序开始运行到clock()被调用时所
耗费的时间。这个时间单位是clock tick,即“时钟打点”。同时还有一个常数CLK_TCK,给出了机器时钟每秒所走的时钟打点数。于是为了获
得一个函数f的运行时间,我们只要在调用f之前先调用clock(),获得一个时钟打点数C1;在f执行完成后再调用clock(),获得另一个时钟打点
数C2;两次获得的时钟打点数之差(C2-C1)就是f运行所消耗的时钟打点数,再除以常数CLK_TCK,就得到了以秒为单位的运行时间。
这里不妨简单假设常数CLK_TCK为100。现给定被测函数前后两次获得的时钟打点数,请你给出被测函数运行的时间。

输入描述:
输入在一行中顺序给出2个整数C1和C1。注意两次获得的时钟打点数肯定不相同,即C1 < C2,并且取值在[0, 107]

输出描述:
在一行中输出被测函数运行的时间。运行时间必须按照“hh:mm:ss”(即2位的“时:分:秒”)格式输出;不足1秒的时间四舍五入到秒。

  • cmath中的函数round(),代表四舍五入取值
#include<iostream>
#include<time.h>
#include<cmath>
#include<cstdio>
#define CLK_TCK 100
using namespace std;

int main(){
	int c1,c2;
	cin>>c1>>c2;
	int ans=round(1.0*(c2-c1)/CLK_TCK);
	int h=ans/3600;
	ans-=3600*h;
	int m=ans/60;
	ans-=60*m;
	printf("%02d:%02d:%02d",h,m,ans);
	return 0;
} 

旧键盘

题目描述
旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出
肯定坏掉的那些键。

输入描述:
输入在2行中分别给出应该输入的文字、以及实际被输入的文字。每段文字是不超过80个字符的串,由字母A-Z(包括大、小写)、数字0-9、
以及下划线“_”(代表空格)组成。题目保证2个字符串均非空。

输出描述:
按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有1个坏键。

#include<iostream>
#include<string.h>
using namespace std;

int main(){
	char a[90],b[90];
	int hashtable[128]={0};
	cin>>a>>b;
	int len1=strlen(a);
	int len2=strlen(b);
	for(int i= 0;i<len1;i++){
		char c1,c2;
		int j;
		for(j=0;j<len2;j++){
			c1=a[i];
			c2=b[j];
			if(c1>='a'&&c1<='z') c1=c1-'a'+'A';
			if(c2>='a'&&c2<='z') c2=c2-'a'+'A';
			if(c1==c2)break;
		}
		if(j==len2&&hashtable[c1]==0){//第二个字符串未出现,且没有输出过 
			cout<<c1;
			hashtable[c1]=1; 
		}
	}
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值