PAT乙级题解61-95
61
#include<bits/stdc++.h>
using namespace std;
int main(){
int N,M;
scanf("%d %d",&N,&M);
int score[M],ans[M];
for(int i=0;i<M;i++) //读入分值
scanf("%d",&score[i]);
for(int i=0;i<M;i++) //读入正确答案
scanf("%d",&ans[i]);
for(int i=0;i<N;i++){
int sum=0;
for(int j=0;j<M;j++){ //比对每个学生答案
int temp;
scanf("%d",&temp);
if(temp==ans[j]) sum+=score[j]; //如果争取则累加得分
}
printf("%d\n",sum); //输出结果
}
return 0;
}
62
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b){
return !b?a:gcd(b,a%b);
}
int main(){
int a,b,c,d,e,cnt=0;
scanf("%d/%d %d/%d %d",&a,&b,&c,&d,&e);
if(a*d>b*c){ //这里保证第一个分数数值小,第二个分数数值大
swap(a,c),swap(b,d);
}
for(int i=a*e/b+1;i*d<c*e;i++){ //i从最低的数开始,到最高的数结束
if(gcd(i,e)==1){ //满足最简分数的进行输出
if(cnt++) putchar(' '); //通过计数的方式处理格式
printf("%d/%d",i,e);
}
}
return 0;
}
63
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8;
#define more(a,b) ((a)-(b)>eps) //浮点数的比较,大于需要超过某个精度范围
int main(){
int a,b,N;
double temp,max=0.0;
scanf("%d",&N);
for(int i=0;i<N;i++){
scanf("%d %d",&a,&b);
temp=hypot(a,b); //返回值为double,返回两个参数平方和的开方
if(more(temp,max)) max=temp; //获取最大模
}
printf("%.2f",max);
return 0;
}
64
#include<bits/stdc++.h>
using namespace std;
int main(){
int Table[37]={0}; //朋友证号最多为36,即数字为9999,所以打表开37个空间即可
char ch;
while((ch=getchar())!='\n') continue; //字符处理,所以不需要知道有多少个数字,直接过滤掉这些字符
int friendnum=0,cnt=0; //friendnum用于存放临时计算出的一个朋友证号,cnt用于计数不同的朋友证号个数
while((ch=getchar())!='\n'){ //到换行结束
if(ch==' '){ //如果遇到空格,说明已经处理过一个数字了
if(Table[friendnum]==0){ //如果第一次遇到这个朋友证号,计数并将标记置为一
cnt++;Table[friendnum]=1;
}
friendnum=0;continue; //凡是处理过一个数字,friendnum清0,用于下一个数字的计算
}
friendnum+=ch-'0'; //累加计算每一位的和
}
if(Table[friendnum]==0){ //处理最后一个数字
cnt++;Table[friendnum]=1;
}
printf("%d\n",cnt); //输出个数
for(int i=1,flag=0;flag<cnt;i++){ //遍历并输出符合的朋友证号
if(Table[i]==1){
if(flag++) putchar(' ');
printf("%d",i);
}
}
return 0;
}
65
#include<bits/stdc++.h>
using namespace std;
int main(){
map<string,string> mp; //记录夫妻关系
map<string,int> at; //记录是否在场
int n,m;
cin>>n;
for(int i=0;i<n;i++){ //读取夫妻关系
string a,b;
cin>>a>>b;
mp[a]=b;
mp[b]=a;
}
vector<string> v1; //记录到场人员
vector<string> v; //记录输出人员
cin>>m;
for(int i=0;i<m;i++){ //出场人员进行标记
string temp;
cin>>temp;
at[temp]=1;
v1.push_back(temp);
}
for(int i=0;i<m;i++){
string temp=v1[i];
if(mp[temp]=="") //如果没有夫妻关系,属于需要输出的人员
v.push_back(temp);
else if(at[mp[temp]]==0){//如果配偶没有到场,也属于需要输出的人员
v.push_back(temp);
}
}
if(v.size()==0){ //如果人数是0直接输出结果
putchar('0');return 0;
}
sort(v.begin(),v.end()); //如果有单身人士,按照id从小到大排序输出
cout<<v.size()<<'\n';
for(int i=0;i<v.size();i++){
if(i) putchar(' ');
cout<<v[i];
}
return 0;
}
66
#include<bits/stdc++.h>
using namespace std;
int main(){
int m,n,a,b,tag;
scanf("%d%d%d%d%d",&m,&n,&a,&b,&tag); //读入行数,列数,替换区间,替换值
for(int i=0;i<m;i++){ //双循环读入
for(int j=0;j<n;j++){
int temp;
scanf("%d",&temp);
if(temp>=a&&temp<=b) temp=tag; //如果符合替换区间,直接替换
if(j) putchar(' ');
printf("%03d",temp); //按照格式进行输出
}
putchar('\n');
}
return 0;
}
67
#include<bits/stdc++.h>
using namespace std;
int main(){
string pasword,temp;
int n,cnt=0;
cin>>pasword>>n; //读入正确密码和允许的错误次数
char ch;
while((ch=getchar())!='\n') continue; //过滤多余字符
while(1){
getline(cin,temp); //读入一个密码输入
if(temp=="#") break; //如果读取结束
else if(temp==pasword){ //如果密码正确,输出欢迎语句并结束循环
printf("Welcome in");break;
}
else{ //如果不正确,输出错误密码,然后统计错误次数
cout<<"Wrong password: "<<temp<<endl;
cnt++; //如果错误次数达到上限,输出账户锁定,并结束循环
if(cnt==n){ printf("Account locked");break;}
}
}
return 0;
}
68
#include<bits/stdc++.h>
using namespace std;
#define diff(a,b) ((a-b)>0?(a-b):(b-a))
int Point[1005][1005]={0};
int main(){
int M,N,TOL,x,y,cnt=0;
map<int,int> mp;
scanf("%d %d %d",&M,&N,&TOL); //读取数据
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
scanf("%d",&Point[i][j]);
mp[Point[i][j]]++;
}
}
for(int i=1;i<=N;i++){
int flag=0;
for(int j=1;j<=M;j++){ //边和角落的点也需要判定,类似于扫雷游戏的判定规则,所以数组开大一些,下标从1开始保存
if(diff(Point[i][j],Point[i][j+1])>TOL //判定是否比周围的颜色相差超过阈值
&&diff(Point[i][j],Point[i][j-1])>TOL
&&diff(Point[i][j],Point[i+1][j+1])>TOL
&&diff(Point[i][j],Point[i+1][j])>TOL
&&diff(Point[i][j],Point[i+1][j-1])>TOL
&&diff(Point[i][j],Point[i-1][j+1])>TOL
&&diff(Point[i][j],Point[i-1][j])>TOL
&&diff(Point[i][j],Point[i-1][j-1])>TOL){
if(mp[Point[i][j]]==1){ //如果这样的点存在,且出现次数只有一次,累计并保存
cnt++;x=i,y=j;
if(cnt>1){flag=1;break;} //如果符合条件的点不止一个,终止循环判定
}
}
}
if(flag) break;
}
if(cnt==0) puts("Not Exist"); //根据结果进行输出
else if(cnt==1) printf("(%d, %d): %d\n",y,x,Point[x][y]);
else puts("Not Unique");
return 0;
}
69
#include<bits/stdc++.h>
using namespace std;
int main(){
int M,N,S;
map<string,int> mp; //用于标记是否出现过
string str;
scanf("%d %d %d\n",&M,&N,&S); //读入各个参数
bool flag=false; //用于标记是否有中奖输出
for(int i=1;i<=M;i++){ //依次读入M个数据
cin>>str; //读入一个ID
if(mp[str]==1) {S=S+1;continue;} //用S记录需要输出的下一个中奖者的序号,如果已经领奖顺延到下一位
if(i==S){ //如果当前序号是中奖着则进行处理
mp[str]=1; //领奖标记
cout<<str<<endl; //输出名字
flag=true; //修改标记
S+=N; //再隔N个为下一个中奖者,更新S
}
}
if(flag==false) printf("Keep going...");//如果没有人中奖
return 0;
}
70
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
double sum;
scanf("%d",&n);
int a[n];
for(int i=0;i<n;i++) //读取n个元素,然后从小到大排序,因为长绳子尽可能少折叠,所以放在最后加入绳结
scanf("%d",&a[i]);
sort(a,a+n);
sum=a[0]; //sum初始化为第一段绳子
for(int i=1;i<n;i++)
sum=(sum+a[i])/2; //和后边的每段绳子进行链接
printf("%d",int(sum)); //通过强制转换截断,向下取整
return 0;
}
71
#include<bits/stdc++.h>
using namespace std;
int main(){
int T,K;
scanf("%d %d",&T,&K);
for(int i=0;i<K;i++){
int n1,b,t,n2;
scanf("%d %d %d %d",&n1,&b,&t,&n2);
if(t>T) printf("Not enough tokens. Total = %d.\n",T); //如果下注超过拥有的筹码
else if((b==1&&n2>n1)||(b==0&&n1>n2)) //如果赢了,则增加筹码
printf("Win %d! Total = %d.\n",t,T+=t);
else{
printf("Lose %d. Total = %d.\n",t,T-=t); //如果输了就减少筹码
if(T==0) {printf("Game Over.");break;} //如果输完了就结束游戏
}
}
return 0;
}
//注意:
//题目输出格式上Total之前只有一个空格,但是输出样例有两个空格,以输出样例为准
72
#include<bits/stdc++.h>
using namespace std;
int main(){
int N,M,Pcnt=0,Tcnt=0; //Pcnt用于记录人数,Tcnt用于记录物品个数
map<int,bool> notallow; //记录违禁物品编号
scanf("%d%d",&N,&M);
for(int i=0;i<M;i++){ //读入并标记违禁物品
int temp;
scanf("%d",&temp);
notallow[temp]=true;
}
for(int i=0;i<N;i++){ //依次对N个学生进行检查
string name;
int k,temp,flag=0; //flag标记为是否有违禁物品
cin>>name>>k;
for(int j=0;j<k;j++){
scanf("%d",&temp);
if(notallow[temp]==true){ //如果是违禁物品,则进行处理
if(flag==0) cout<<name<<":";//如果是第一个违禁物品,先输出人名
printf(" %04d",temp); //输出违禁物品编号
flag=1; Tcnt++; //修改标记,并累加
}
}
if(flag==1){putchar('\n'); Pcnt++;}//如果该学生有违禁物品则统计人数,并换行
}
printf("%d %d",Pcnt,Tcnt); //输出最后的统计人数
return 0;
}
73
#include<bits/stdc++.h>
using namespace std;
typedef struct{ //题目结构体,score表示分数,ans表示答案用模拟的二进制形式表示,rn表示正确的选项个数
int score,ans,rn,xs[6]; //xs用于存放错误选项的信息,0号储存本题中错误数量最大的个数
}QU;
int getans(); //读取答案
int cmp(QU *p,int i); //比较函数,比较答案,返回错误类型,1代表全对,2代表对一半,3代表错误
int main(){
int N,M,max=0;
char ch;
QU *p;
cin>>N>>M;
p=(QU*)malloc((M+1)*sizeof(QU)); //构造题目结构体数组
for(int i=1;i<=M;i++){ //读入题目,初始化题目结构体的内容
scanf("%d %*d %d",&p[i].score,&p[i].rn);//读入分数和正确选项个数,跳过选项数量,统一按5个选项处理
p[i].ans=getans(); //读取答案
for(int j=0;j<=5;j++){ //将题目每个选项的错误数量初始化为0
p[i].xs[j]=0;
}
}
for(int i=0;i<N;i++){ //读入N个学生答案
double sum=0;
char ch;
for(int j=1;j<=M;j++){
while((ch=getchar())!='(') //过滤吸收多余字符,直到左括号
continue;
switch(cmp(p,j)){ //比对答案
case 1:sum+=p[j].score;break;//如果全对,加上该题分值
case 2:sum+=(1.0*p[j].score)/2;max=(p[j].xs[0]>max?p[j].xs[0]:max);break;//如果对了一般,加一半分值,更新最大错误max
case 3:max=(p[j].xs[0]>max?p[j].xs[0]:max);break;//如果错误,更新max
default:break;
}
}
printf("%.1f\n",sum); //打印成绩
}
if(max==0) //没有人错
puts("Too simple");
else{
for(int i=1;i<=M;i++) //按顺序读取每一个题目
if(p[i].xs[0]==max){ //如果最大错误数量与max相同,则考虑打印
for(int j=1;j<=5;j++){ //比较每个选项的错误数量,按顺序输出与max相等的选项
if(p[i].xs[j]==max)
printf("%d %d-%c\n",max,i,'a'-1+j);
}
}
}
free(p); //释放动态内存空间
return 0;
}
int getans() //读取答案,模拟二进制数的表示方法
{
int ans=0;
char ch;
while((ch=getchar())!=')'){
if(ch=='\n') break;
switch(ch){
case 'a':ans+=10000;break;
case 'b':ans+=1000;break;
case 'c':ans+=100;break;
case 'd':ans+=10;break;
case 'e':ans+=1;break;
default:break;
}
}
return ans;
}
int cmp(QU *p,int i)
{
int ret=3; //ret返回值表示题目错误类型,默认为错题
int ans=getans(); //读取答案
char a[6],pa[6]; //定义两个字符串,把答案读入字符串进行比对
sprintf(a,"%05d",ans); //把答案以5位字符串的格式读入,不够的补零
sprintf(pa,"%05d",p[i].ans); //pa表示答案字符串
int cnt=0; //只统计正确选项的数量
for(int j=0;j<5;j++){ //依此比对答案
if(pa[j]==a[j]){ //如果相同
if(pa[j]=='1') cnt++; //如果答案是1,表示选中,cnt计数;如果是0,则表示该选项不存在或者不需要选
}
else{ //如果不相同则表示漏选或者多选 ,都认为此选项出错 ,统计在错误数量内
p[i].xs[j+1]++;
if(pa[j]=='0') cnt=10; //如果答案是0,表示错选,将cnt置为一个很大的值,以表示此题错误,漏选则cnt不做处理
}
}
for(int j=0;j<=5;j++){ //遍历选项错误数量,将错的最多的赋值给0号位置;
p[i].xs[0]=(p[i].xs[j]>p[i].xs[0]?p[i].xs[j]:p[i].xs[0]);
}
if(cnt==p[i].rn) ret=1; //如果选对的数量和正确答案的数量相同,表示全对
else if(cnt<p[i].rn) ret=2; //如果选对的数量小于正确答案的数量,表示对了一半
//否则,cnt是一个很大的值,表示此题错误
return ret;
}
74
#include<bits/stdc++.h>
using namespace std;
int get_arry(int a[]){ //把数字的每一位读入int数组
char ch;
int cnt=0;
while((ch=getchar())!='\n')
a[cnt++]=ch-'0';
return cnt;
}
void Reverse(int a[],int len){ //逆置函数
int i=0,j=len-1;
while(i<j){
swap(a[i],a[j]);
i++,j--;
}
}
int main(){
int Table[21]={0},a[21]={0},b[21]={0}; //每一位的权值Table,第一个数a,第二个数b
int cnt,lena,lenb,flag=0; //长度计数器和标记
cnt=get_arry(Table),lena=get_arry(a);lenb=get_arry(b); //读入每一个数字的每一位
Reverse(Table,cnt);Reverse(a,lena);Reverse(b,lenb); //将每一个数组逆置
for(cnt=0;cnt<lena||cnt<lenb||flag;cnt++){ //遍历数组,以最长的为结尾,flag用于存放位的临时和以及进位,如果最后还有进位flag不为0,则多一步处理
int tag=Table[cnt]==0?10:Table[cnt]; //获取当前位的权值,0代表权值是10,需要特判
flag=a[cnt]+b[cnt]+flag; //计算当前两位的和需要累加上一位的进位
a[cnt]=flag%tag; //计算累加后的位存放再a中
flag/=tag; //更新获取进位
}
flag=0; //标记,第一个非零的位开始输出
for(cnt--;cnt>=0;cnt--){ //cnt记录了最终结果的长度,倒序输出
if(a[cnt]!=0) flag=1; //如果出现了第一位不为0的数字,修改标记
if(flag==1)
putchar('0'+a[cnt]); //第一位不为0的出现后开始输出
}
if(flag==0) putchar('0'); //如果全为0,则flag标记为初始化的0,特别输出加法结果0
return 0;
}
75
解法一
#include<bits/stdc++.h>
using namespace std;
typedef struct{
int id,data,next;
}NODE;
NODE LinkList[100001]; //存放读入的数据结点
NODE out[100001]; //用辅助的数组空间存放最终的链表
int main(){
int head,n,k,cnt=0,i;
scanf("%d %d %d",&head,&n,&k); //读入参数
for(i=0;i<n;i++){
int temp;
scanf("%d",&temp);
LinkList[temp].id=temp;
scanf("%d %d",&LinkList[temp].data,&LinkList[temp].next);
}
for(i=head;i!=-1;i=LinkList[i].next){ //先存入小于0的结点
if(LinkList[i].data<0)
out[cnt++]=LinkList[i];
}
for(i=head;i!=-1;i=LinkList[i].next){ //再存放0~K的结点
if(LinkList[i].data>=0&&LinkList[i].data<=k)
out[cnt++]=LinkList[i];
}
for(i=head;i!=-1;i=LinkList[i].next){ //最后存放剩余结点
if(LinkList[i].data>k)
out[cnt++]=LinkList[i];
}
for(i=0;i<cnt-1;i++){ //格式化输出链表,next值便是数组中下一个元素的id,最后一个结点单独处理
printf("%05d %d %05d\n",out[i].id,out[i].data,out[i+1].id);
}
printf("%05d %d -1",out[i].id,out[i].data);
return 0;
}
解法二
#include<bits/stdc++.h>
using namespace std;
typedef struct{
int id,data,next;
}NODE;
NODE LinkList[100001]; //存放读入的数据结点
NODE out[100001]; //用辅助的数组空间存放最终的链表
int main(){
int head,n,k,cnt=0,i; //cnt从0开始,是负值存放位置的开始
int negcnt=0,Kcnt=0; //negcnt为负值结点个数,Kcnt为0~K结点个数
int Kindex,OtherIndex; //Kindex是0~K值最终在数组存放的数组下标起始位置,OtherIndex是大于K的元素下标起始位置
scanf("%d %d %d",&head,&n,&k); //读入参数
for(i=0;i<n;i++){
int temp;
scanf("%d",&temp);
LinkList[temp].id=temp;
scanf("%d %d",&LinkList[temp].data,&LinkList[temp].next);
}
for(i=head;i!=-1;i=LinkList[i].next){ //第一遍遍历链表,记录每种类型的个数
if(LinkList[i].data<0) negcnt++;
else if(LinkList[i].data>=0&&LinkList[i].data<=k) Kcnt++;
}
Kindex=negcnt; OtherIndex=negcnt+Kcnt; //计算每类元素存放的起始坐标
for(i=head;i!=-1;i=LinkList[i].next){
if(LinkList[i].data<0) //如果是负值,从cnt开始存放
out[cnt++]=LinkList[i];
else if (LinkList[i].data>=0&&LinkList[i].data<=k) out[Kindex++]=LinkList[i]; //如果是0~K值从Kindex位置开始存放
else out[OtherIndex++]=LinkList[i]; //大于K的从OtherIndex位置开始存放
} //显然最后OtherIndex刚好是最后一个元素的下一个位置下标,也刚好是链表长度
for(i=0;i<OtherIndex-1;i++){ //格式化输出链表,next值便是数组中下一个元素的id,最后一个结点单独处理
printf("%05d %d %05d\n",out[i].id,out[i].data,out[i+1].id);
}
printf("%05d %d -1",out[i].id,out[i].data);
return 0;
}
76
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){ //读取N组数据
for(int j=0;j<4;j++){ //每组四个选项
string str;
cin>>str; //读入字符串
if(str[2]=='T') //如果该答案是正确的,输出对应的序号
printf("%d",str[0]+1-'A');
}
}
return 0;
}
77
#include<bits/stdc++.h>
using namespace std;
int main(){
int N,M;
scanf("%d%d",&N,&M);
for(int i=0;i<N;i++){
int G2,cnt=0,maxs=0,mins=M; //cnt用于记录有效分数的个数,maxs和mins用于记录最大和最小成绩
double G1=0;
scanf("%d",&G2);
for(int j=0;j<N-1;j++){
int score;
scanf("%d",&score);
if(score<0||score>M) continue; //不合法成绩直接跳过不处理
G1+=score; //累加合法成绩
maxs=max(maxs,score); mins=min(mins,score); //记录最大和最小成绩
cnt++; //计数器自增
}
G1-=maxs,G1-=mins;G1=G1/(cnt-2); //G1减去最大最小分数,然后求平均数
printf("%d\n",int((G1+G2)/2+0.5)); //四舍五入后取整并输出,这里使用+0.5并强制转换的方式实现
}
return 0;
}
78
#include<bits/stdc++.h>
using namespace std;
void Cstr(){ //压缩算法
int cnt=1; //统计字符个数
char ch=getchar(); //先读入第一个字符,因为后序字符需要有一个前置字符进行比对
while(ch!='\n'){ //在读到换行之前都要处理
char temp=getchar(); //读取当前位的字符
if(temp==ch) cnt++; //如果和前置字符相同则进行统计相同字符个数
else{ //如果不同则进行输出
if(cnt>1) printf("%d%c",cnt,ch); //如果超过1个,则输出个数和字符
else putchar(ch); //否则输出一个字符即可
cnt=1;ch=temp; //更新计数器重新计数,更新ch为当前字符,用于准备下一次比对
}
}
}
void Dstr(){
char ch,num[15]; //ch用于存储字符,num用于存储整数
while((ch=getchar())!='\n'){ //在未读到换行时进行判定
if(isdigit(ch)){ //如果是数字,则需要读取一个完整的数字
int index=0; //存放数字的数组下标
while(isdigit(ch)){ //如果是数字则进行存储,否则刚好获取到字符个数,和需要输出的字符ch
num[index++]=ch;
ch=getchar();
}
num[index]='\0'; //添加字符结尾标记
sscanf(num,"%d",&index); //将字符数组转化为整型数字
for(int i=0;i<index;i++) putchar(ch); //输出相对应个数的字符
}
else putchar(ch); //如果只有一个字符(没有数字修饰)直接输出
}
}
int main(){
char ch=getchar(); //读取解压模式
getchar(); //吸收换行符
if(ch=='C') Cstr(); //根据模式选择相应的解压缩算法
else Dstr();
return 0;
}
79
#include<bits/stdc++.h>
using namespace std;
char num[1001],revnum[1001];
bool IsRight(char str[]){ //判断字符串是不是回文数
int low=0,high=strlen(str)-1; //双指针,一个从前往后,一个从后往前,如果对称位置有不相等的就不是回文数
while(low<high){
if(str[low]!=str[high]) return false;
low++,high--;
}
return true;
}
void AddNum(){ //对原始数字进行加法操作
int len=strlen(num); //计算字符数组长度
int i=0,flag=0;
for(i=0;i<len;i++) revnum[i]=num[len-1-i]; //获取逆序后的字符串
revnum[i]='\0'; //注意字符串的结尾符号
printf("%s + %s = ",num,revnum); //输出加法算式
for(i=0;i<len;i++){ //大数加法
flag=num[i]-'0'+revnum[i]-'0'+flag;
num[i]=flag%10+'0';
flag/=10;
}
if(flag) num[i++]=flag+'0'; //如果还有进位,需要多出一位
num[i]='\0'; //字符串末尾处理
int low=0,high=i-1; //由于得到的字符串实际上是逆位的,所以逆转一下
while(low<high){ swap(num[low],num[high]); low++,high--; }
printf("%s\n",num); //输出计算过后的结果
}
int main(){
scanf("%s",num);
if(IsRight(num)){ //特判给的第一个数字就是回文数
printf("%s is a palindromic number.",num); return 0;
}
int i=10;
while(i--){ //循环10次,
AddNum(); //加法处理
if(IsRight(num)){ //如果得到一个回文数,输出并结束循环
printf("%s is a palindromic number.",num);
break;
}
} //如果刚好第10步得到回文数,则i为0,如果10步都没得到,i最后为-1
if(i==-1) printf("Not found in 10 iterations.");//如果10步以内没有找到
return 0;
}
//测试点2 3 4是给出的数字便是回文数,所以直接特判输出即可
80
#include<bits/stdc++.h>
using namespace std;
typedef struct node{
string id;
int Gp=-1,Gmid=-1,Gfi=-1,G; //各项成绩初始化为-1
}STU;
bool cmp(STU &a,STU &b){
if(a.G!=b.G) return a.G>b.G;
else return a.id<b.id;
}
STU DATA[10005]; //编程成绩有效个数一定小于等于P,所以最多只有P个人
int main(){
int P,M,N,cnt=0,score;
string id;
map<string,int> mp;
scanf("%d %d %d",&P,&M,&N);
for(int i=0;i<P;i++){ //读取编程成绩
cin>>id>>score;
if(score<200) continue; //如果编程分数不及格,直接跳过
DATA[cnt].id=id; //记录学生成绩和学号
DATA[cnt].Gp=score;
mp[id]=cnt; cnt++; //cnt用于记录数组中下一个可存放位置的下标,mp用于存放学号对应的数组下标
}
for(int i=0;i<M;i++){ //读取期中成绩
cin>>id>>score;
if(mp.find(id)==mp.end()) continue; //如果没有编程成绩,直接跳过(这里用mp.find()进行判定)
DATA[mp[id]].Gmid=score; //记录期中成绩
}
for(int i=0;i<N;i++){ //读取期末成绩
cin>>id>>score;
if(mp.find(id)==mp.end()) continue; //如果没有编程成绩,则跳过
int index=mp[id]; //获取在数组中的下标
DATA[index].Gfi=score; //记录期末成绩
if(score<DATA[index].Gmid) DATA[index].G=int(0.4*DATA[index].Gmid+0.6*score+0.5);
else DATA[index].G=score; //按照规则计算最终成绩,这里使用+0.5后强制转换的方式实现四舍五入到整数
}
sort(DATA,DATA+cnt,cmp); //按照要求排序
for(int i=0;i<cnt;i++){ //输出符合要求的学生
if(DATA[i].G<60) break;
cout<<DATA[i].id<<' '<<DATA[i].Gp<<' '<<DATA[i].Gmid<<' '<<DATA[i].Gfi<<' '<<DATA[i].G<<endl;
}
return 0;
}
81
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
scanf("%d\n",&n); //读取输入个数,这里需要带上\n用于吸收末尾的换行符
for(int i=0;i<n;i++){
string str="";
getline(cin,str); //读取整行字符
int len=str.size();
if(len<6) puts("Your password is tai duan le."); //如果密码过短
else{
bool alphcnt=0,numcnt=0,other=0; //如果长度符合要求,验证字母,数字和其他字符
for(int j=0;j<len;j++){
if(isdigit(str[j])) numcnt=1; //如果存在数字
else if(isalpha(str[j])) alphcnt=1; //如果存在字母
else if(str[j]!='.'){ //如果不是字母,不是数字,也不是. 则为其他字符,更新标记并直接退出循环
other=1; break;
}
}
if(other) puts("Your password is tai luan le."); //输出有其他字符
else if(numcnt==0) puts("Your password needs shu zi."); //缺少数字
else if(alphcnt==0) puts("Your password needs zi mu."); //缺少字母
else puts("Your password is wan mei."); //如果都没有上述问题,则认为是完美密码
}
}
return 0;
}
82
#include<bits/stdc++.h>
using namespace std;
int main(){
int id,N,maxid,minid,max_s=0,min_s=20000; //记录最大和最小的id和成绩
scanf("%d",&N);
for(int i=0;i<N;i++){
int x,y;
scanf("%d%d%d",&id,&x,&y);
x=x*x+y*y; //计算当前坐标的平方和
if(x>max_s){ max_s=x; maxid=id; } //分别更新最大和最小值
if(x<min_s){ min_s=x; minid=id; }
}
printf("%04d %04d",minid,maxid); //距离越近,成绩越高,所以先输出min再输出max
return 0;
}
83
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
scanf("%d",&n);
map<int,int> mp;
for(int i=1;i<=n;i++){ //用mp统计每一个数的出现次数,
int temp;
scanf("%d",&temp);
mp[abs(i-temp)]++;
}
for(auto it=mp.rbegin();it!=mp.rend();it++)//从大到小输出重复出现的数字,出现次数大于1认为是重复
if(it->second>1)
printf("%d %d\n",it->first,it->second);
return 0;
}
84
#include<bits/stdc++.h>
using namespace std;
int main(){
string str;
int n,i,j;
cin>>str>>n; //读入第一个字符
for(int cnt=1;cnt<n;cnt++){ //循环n-1次即可,因为第一行就是给出的字符
string temp=""; //根据前一个字符串,temp用于构建新字符
for(i=0;i<str.size();i=j){ //遍历字符串
for(j=i;j<str.size()&&str[j]==str[i];j++);//如果j位置的字符串和i位置的相同,一直往后统计,直到结束或者遇到不相同的字符
temp+=str[i]+to_string(j-i); //先加上当前的字符,然后加上个数,然后用新位置j在外层循环更新i的值
}
str=temp; //更新字符串
}
cout<<str;
return 0;
}
85
#include<bits/stdc++.h>
using namespace std;
typedef struct node{
string id;
int AS=0,BS=0,TS=0,S=0,cnt=0;
}SCH;
bool cmp(SCH &a,SCH &b){ //排序规则
if(a.S!=b.S) return a.S>b.S; //加权分数按照从高到底排序
else if(a.cnt!=b.cnt) return a.cnt<b.cnt; //分数并列,按照人数从少到多排序
else return a.id<b.id; //人数依然并列按照学校名字字典序排列
}
int main(){
int n,cnt=0;
scanf("%d",&n);
SCH DATA[n];
unordered_map<string,int> mp; //记录学校在数组中的下标,使用无序map以节省时间
for(int i=0;i<n;i++){
string id,sch;
int score,index;
cin>>id>>score>>sch;
for(int k=0;k<sch.size();k++){ //把所有的学校名字都改为小写
if(sch[k]>='A'&&sch[k]<='Z') sch[k]=sch[k]-'A'+'a';
}
if(mp.find(sch)==mp.end()) {DATA[cnt].id=sch; mp[sch]=cnt++;} //如果出现一个心学校,则从数组中分配一个位置,并更新mp
index=mp[sch]; //获取学校存储下标
DATA[index].cnt++; //人数累加
switch(id[0]){ //根据考试难度累加分数
case 'A':DATA[index].AS+=score;break;
case 'B':DATA[index].BS+=score;break;
case 'T':DATA[index].TS+=score;break;
}
} //遍历以计算加权分数
for(int i=0;i<cnt;i++) DATA[i].S=int(1.0*DATA[i].BS/1.5+DATA[i].AS+1.5*DATA[i].TS);
sort(DATA,DATA+cnt,cmp); //按照规则排序
int rank=1;
cout<<cnt<<endl; //输出学校个数
for(int i=0;i<cnt;i++){
if(i==0) rank=1; //第一个人序号是1
else if(DATA[i].S!=DATA[i-1].S) rank=i+1;//如果和前一个人分数相同,序号相同,如果分数不同,排名为自己在数组中的序号(由于数组从0开始,排序从1开始,所以要+1)
cout<<rank<<' '<<DATA[i].id<<' '<<DATA[i].S<<' '<<DATA[i].cnt<<endl;
}
return 0;
}
86
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b,temp,i,ans[7]={0};
scanf("%d %d",&a,&b);
temp=a*b;
for(i=0;temp;i++){ //把每一位存在数组中(逆序)
ans[i]=temp%10;
temp/=10;
}
for(temp=0;ans[temp]==0;temp++);//找到第一个非零数字开始输出
for(;temp<i;temp++)
printf("%d",ans[temp]);
return 0;
}
87
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
set<int> se;
scanf("%d",&n);
for(int i=1;i<=n;i++){ //根据要求计算数值,并用set存储去重
int temp=int(i/2)+int(i/3)+int(i/5);
se.insert(temp);
}
printf("%d",se.size());
return 0;
}
88
#include<bits/stdc++.h>
using namespace std;
void check(double x,double m){ //打印能力值关系
if(x>m) printf(" Cong");
else if(x==m) printf(" Ping");
else printf(" Gai");
}
int main(){
int M,x,y,flag=0;
int jia,yi;
double bing; //bing的能力值是除法计算出来的,所以,可能是浮点数
scanf("%d %d %d",&M,&x,&y); //读取数据
for(jia=99;jia>=10;jia--){ //甲能力值为两位数,而且解不唯一时以最大为准
yi=jia%10*10+jia/10;
int diff=abs(jia-yi);
if(diff*y==yi*x){ //计算满足条件的关系
bing=1.0*diff/x;
flag=1;break; //有解就把标记置为一
}
}
if(flag==0) printf("No Solution"); //无解的情况
else{
printf("%d",jia); //输出有解的情况
check(jia,M);check(yi,M);check(bing,M);
}
return 0;
}
89
#include<bits/stdc++.h>
using namespace std;
int main(){
int N;
cin>>N;
vector<int> v(N+1);
for(int i=1;i<=N;i++) //用于存放每一个玩家说的数字
cin>>v[i];
for(int i=1;i<=N;i++){ //双重循环,这样可以得到题目所说的最小序列
for(int j=i+1;j<=N;j++){
vector<int> lie,a(N+1,1); //记录说谎者和假定的身份(1表示好人,-1表示狼人,初始化为1)
a[i]=a[j]=-1; //假定i和j都是狼人
for(int k=1;k<=N;k++){ //遍历每个人说的话
if(v[k]*a[abs(v[k])]<0) //v表示第k个玩家说的话,与相对应的描述的另一位玩家abs[v[k]]的身份进行比对,如果符号(身份)不同,乘积小于0,即说明此人说谎
lie.push_back(k); //保存说谎玩家的序号
}
if(lie.size()==2&&a[lie[0]]+a[lie[1]]==0){ //如果说谎玩家刚好有两个,而且一个狼人一个好人(题目要求只有两个狼人,有狼人说谎且不是所有狼人都说谎)
cout<<i<<' '<<j; //如果满足题目条件,说明当前的假设成立,也就是i和j都是狼人,输出即可
return 0;
}
}
}
cout<<"No Solution"; //如果没有满足条件的输出,则无解
return 0;
}
90
#include<bits/stdc++.h>
using namespace std;
unordered_map<string,string> mp; //记录反应物对应关系
bool check(){
int n;
cin>>n;
unordered_map<string,int> m; //记录某个物品是否出现过
vector<string> v(n);
for(int i=0;i<n;i++){ //读取每一种货物
cin>>v[i];
m[v[i]]=1;
}
for(int i=0;i<n;i++)
if(mp[v[i]]!=""){ //如果当前物品有反应物
for(int j=0;j<mp[v[i]].size();j+=5){
string temp=mp[v[i]].substr(j,5); //每次提取从j开始的五位进行核查
if(m[temp]==1) return false; //如果与之反应的物品也出现在清单里,则不能安全运输
}
}
return true;
}
int main(){
int n,m;
string a,b;
cin>>n>>m;
for(int i=0;i<n;i++){ //采用衔接的方式构建一个类似于二维矩阵的map,
cin>>a>>b; //把每一个物品对应的反应物品string类变量直接加在value值的后边,构成一个长串
mp[a]+=b; //检查时每次取出5位进行对比核查
mp[b]+=a;
}
for(int i=0;i<m;i++) //判定m箱货物清单
puts(check()?"Yes":"No");
return 0;
}
Comments | NOTHING