nenuacm 2019 新生训练#10 字符串处理 题解

mac2026-05-26  0

题目链接

Ultra-Fast Mathematician

解题思路:

题目说辣么多,其实就是将两个二进制进行异或运算:相同位上的数字相同,异或结果为0,否则为1

AC代码

#include<bits/stdc++.h> using namespace std; int main(){ char s[105],t[105],r[105]; memset(r,'\0',sizeof(r)); cin>>s>>t; for(int i=0;s[i]!='\0';++i){ if(s[i]==t[i])r[i]='0'; else r[i]='1'; } cout<<r<<endl; return 0; }

Fox And Snake

解题思路

按规律输出,当i为奇数时,输出的一行全部为’#’;当i为偶数时,用flag做开关,交换输出两种格式

AC代码

#include<bits/stdc++.h> using namespace std; #define FOR(a,b,c) for(int i=a;i<=b;++i)printf("%c",c) int n,m;bool flag; int main(){ cin>>n>>m;flag=false; for(int i=1;i<=n;++i){ if(i%2)FOR(1,m,'#'); else{ if(!flag){FOR(1,m-1,'.');cout<<'#';flag=true;} else{cout<<'#';FOR(2,m,'.');flag=false;} } cout<<endl; } return 0; }

Pangram

解题思路

如果输入的字符串中包含26个字母,则输出"YES",否则输出"NO"

AC代码

#include<bits/stdc++.h> using namespace std; int main(){ int n;cin>>n;getchar();map<int,bool> mp; for(int i=0;i<26;++i)mp[i]=false; char str[105];cin>>str; for(int i=0;i<n;++i){ if(str[i]>='A'&&str[i]<='Z')mp[str[i]-'A']=true; if(str[i]>='a'&&str[i]<='z')mp[str[i]-'a']=true; } bool flag=false; for(int i=0;i<26;++i) if(!mp[i]){flag=true;break;} if(flag)cout<<"NO"<<endl; else cout<<"YES"<<endl; return 0; }

String Task

解题思路

要求删除给定字符串中出现的6个元音字母,输出的时候在每个辅音字母前面加一个字符’.’,并且输出全部为小写。这里边判断边输出

AC代码

#include <iostream> #include <algorithm> #include <iomanip> #include <cmath> #include <cstdio> #include <vector> #include <cstring> using namespace std; int main() { std::ios::sync_with_stdio(false); char s[200]; cin>> s; for (int i=0;s[i]!='\0';i++) { if (s[i]=='A' || s[i]=='O' || s[i]=='Y' || s[i]=='E' || s[i]=='U' || s[i]=='I' || s[i]=='a' || s[i]=='o' || s[i]=='y' || s[i]=='e' || s[i]=='u' || s[i]=='i' ) continue; else { cout << "."; if (s[i]<97) { s[i]+=32; cout << s[i];} else cout << s[i]; } } }

考试排名

解题思路

题目要求讲得很清楚,给出n个考试题目,单位罚时分为m,循环读入参赛人员的信息,没有限制参赛人数,但从AC时间小于1000,提交次数总是小于100来看,参赛人数即结构体数组长度开个(1W+1)就够了。输出规则是先按AC题目的数量从大到小排,再按AC总用时从小到大排,如果前两者相等,则按名字的字典序输出。另外用for循环读入每道题的情况,然后进行字符串处理,当遇到第一个字符是’-'或者该字符串是"0",则continue继续读取,不进行下步操作。

AC代码

#include <bits/stdc++.h> #define MAXN 10001 using namespace std; struct node { char name[15];//用户名 int ac;//ac的题目数量 int time;//总共花的时间 }stu[MAXN];//参加比赛的人数 bool cmp(node x,node y)//结构体排序规则 { if(x.ac!=y.ac)return x.ac>y.ac;//先按ac的题量从大到小排 else if(x.time!=y.time)return x.time<y.time;//再按时间从小到大排 else return strcmp(x.name,y.name)<0;//最后是按字典序排名 } int main() { int n,m,t=0;//n为考试题数,m为单位罚分数,t表示参赛人员的序号标记 char ch[10];//输入每个题的得分情况 cin>>n>>m; getchar(); //吃掉回车符 while(cin>>stu[t].name){//不断输入参赛人员的比赛信息 stu[t].ac=stu[t].time=0;//同时初始化为0,下面进行计算 for(int i=0;i<n;i++){ //循环读个n个题目的比赛情况 cin>>ch; if((ch[0]=='-')||(strcmp(ch,"0")==0))continue;//等于负数或为0,说明没有AC,直接进行下一个输入 stu[t].ac++;//AC了就先计数,接下来算AC这道题所用的时间 int j,tmp=0; for(j=0;j<(int)strlen(ch)&&ch[j]!='(';j++) tmp=tmp*10+ch[j]-'0';//先计算左括号旁边的数字 stu[t].time+=tmp;//先加解题所用的时间 tmp=0; if(j<(int)strlen(ch)){ for(int k=j+1;k<(int)strlen(ch)-1;k++) //计算括号内的数 tmp=tmp*10+ch[k]-'0'; } stu[t].time+=tmp*m;//加上(之前错误提交次数乘上罚时总用时) } t++;//计数参赛人数 } sort(stu,stu+t,cmp); //按规则排序 for(int i=0;i<t;i++) // 输出排名信息 printf("%-10s %2d %4d\n",stu[i].name,stu[i].ac,stu[i].time);//按格式输出 return 0; }

水果

解题思路

这道题的要求就是相同产地归为一类,相同水果进行计数,且两者都是按字典序输出的,很基础的题目。怎么处理相同产地相同种类的水果数呢?我的做法就是如果当前的这条记录与下一条记录有相同的产地和相同的某种水果,就将这条记录的num计数存放到下一个记录中,同时将这条记录的num赋值为0,如果当前记录与下一个不相同的时候就先输出当前的产地,然后从前往当前遍历,如果产地相同,且num不为0,即可输出当前产地某种水果的总数量。(已经按字典排序了)

AC代码

#include<bits/stdc++.h> using namespace std; struct node { char fruit[81];//水果名称 char area[81];//产地名称 int num;//交易次数 }c[101]; bool cmp(node x,node y)//排序规则 { if(strcmp(x.area,y.area)<0)return true;//产地先从小到大排序 if(strcmp(x.area,y.area)==0 && strcmp(x.fruit,y.fruit)<0)return true;//如果产地相同,则按照字典将水果排序 return false;//否则返回假 } int main() { int N,M; cin>>N; while(N--){ //测试数据组数 cin>>M; getchar(); //吃掉回车符 for(int i=0;i<M;i++)//M次交易 cin>>c[i].fruit>>c[i].area>>c[i].num; sort(c,c+M,cmp);//按规则排序 for(int i=0;i<M;i++){ if(strcmp(c[i].area,c[i+1].area)==0){//如果当前产地与下一个产地相同 if(strcmp(c[i].fruit,c[i+1].fruit)==0){//且水果名称相同 c[i+1].num+=c[i].num;//则将水果数目进行相加 c[i].num=0;//将原来的水果数目清空 } } else{//如果不同 cout<<c[i].area<<endl;//不同就先输出产地 for(int j=0;j<M;j++){//依次再进行比较 if(strcmp(c[i].area,c[j].area)==0 && c[j].num)//找到一个num是不为0的,即该产地某种水果的总数 cout<<" |----"<<c[j].fruit<<'('<<c[j].num<<')'<<endl;//输出最后的水果数 } } } if(N!=0)cout<<endl;//案例之间输出空行 } return 0; }

解题思路

1到n每个元素只会出现一次,引入hash[]来记录该数是否已经出现,出现为1,否则为0 ; 读入一个数t ,从1到t-1依次判断是否有hash[t-i]+hash[t+i]==1即以t为中项, 对于t-i,t+i是否仅出现过一个,由于是按顺序读入的,即可保证t-i和t+i在原序列中一定是在t的两边

AC代码

#include<bits/stdc++.h> using namespace std; #define N 10005 int main() { int T,t,n,i,m,flag,hash[N]; scanf("%d",&T); while(T--) { scanf("%d",&n); memset(hash,0,sizeof(hash)); m=n; flag=0; while(m--) { scanf("%d",&t); hash[t]=1; for(i=1;!flag&&i<t&&t+i<=n;i++) { if(hash[t-i]+hash[t+i]==1) //这两个元素有且只有一个出现 flag=1; } } if(flag) printf("Y\n"); else printf("N\n"); } return 0; }

Equations

解题思路

哈希

AC代码

#include <iostream> #include <stdio.h> #include <algorithm> #include <memory.h> using namespace std; int f1[1000005]; //保存得数是正的 int f2[1000005]; //保存得数是负的 int main() { int i, j, k, sum; int a, b, c, d; while(scanf("%d %d %d %d", &a, &b, &c, &d) != EOF) { //abcd全部大于0或者小于0,肯定无解。要加上这个,不然超时 if(a>0 && b>0 && c>0 && d>0 || a<0 && b<0 && c<0 && d<0) { printf("0\n"); continue; } memset(f1, 0, sizeof(f1)); memset(f2, 0, sizeof(f2)); for(i = 1; i <= 100; i++) { for(j = 1; j<= 100; j++) { k = a*i*i + b*j*j; if(k >= 0) f1[k]++; //k>=0 f1[k]++ else f2[-k]++; //k<0 f2[k]++ } } sum = 0; for(i = 1; i <= 100; i++) { for(j = 1; j<= 100; j++) { k = c*i*i + d*j*j; if(k > 0) sum += f2[k]; //若k为正,加上的f2[k] else sum += f1[-k]; //若k为负,加上的f1[k] } } printf("%d\n", 16*sum); //每个解有正有负,结果有2^4种 } return 0; }

统计难题

解题思路

字典树

AC代码

#include<iostream> #include<string.h> #include<stdio.h> using namespace std; char s[1000]; int k,ans; struct Tree{ int A[30],v; ins(){ memset(A,0,sizeof(A)); v=0; } }T[500010]; void build(int f,int l){ int i,n=strlen(s),v=s[l]-'a'; if(l==n) return; if(T[f].A[v]==0){ k++; T[f].A[v]=k; } T[T[f].A[v]].v++; build(T[f].A[v],l+1); } int q(int f,int l){ int i,n=strlen(s),v=s[l]-'a'; if(l==n) return T[f].v; if(T[f].A[v]==0) return 0; return q(T[f].A[v],l+1); } int main(){ k=0; int i; for(i=0;i<500000;i++) T[i].ins(); while(gets(s)){ if(strlen(s)==0) break; build(0,0); } while(gets(s)!=NULL){ ans=q(0,0); printf("%d\n",ans); } return 0; }
最新回复(0)