CUGBACM14级喜迎开学第1场 解题报告

本文解析了多个ACM竞赛题目,包括字符串压缩、模拟算法、过道搬运等,提供了详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

赛后AK。

A  HDU 1020
字符串。压缩编码。遇到与前一字符不同的字符输出统计数据和前一字符,最后一个单独处理。
   
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#define PI acos(-1)
using namespace std;
int main()
{
int c,c1;
char b[10010];
int n;
scanf("%d",&n);
while(n--){
scanf("%s",b);
c=0;
int i;
for(i=0;b[i]!='\0';i++){
if(i==0){
c=0;
}
if(i!=0&&b[i]!=b[i-1])
{
if(c>1)printf("%d%c",c,b[i-1]);
else printf("%c",b[i-1]);
c=0;}
c++,c1=c;
 
}
if(c1>1)printf("%d%c",c1,b[i-1]);
else printf("%c",b[i-1]);
printf("\n");
}
return 0;
}

B  HDU 1032
单纯模拟 因为tep初值赋早了而卡,看来刷题不够多。
    
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<ctype.h>
#define PI acos(-1)
using namespace std;
int f(int x){
int y=1;
while(x!=1){
if(x%2==1)x=(3*x+1)/2,y+=2;
else x=x/2,y++;
}
return y;
}
int main()
{
int i,j;
char s[100],tp[100];
int res;
int tep;
int k,kk;
while(~scanf("%d%d",&i,&j)){
tep=0;
if(i>j)tep=i,i=j,j=tep;
res=f(i);
for(k=i+1;k<=j;k++){
res=max(res,f(k));
}
if(tep==0)printf("%d %d %d\n",i,j,res);
else printf("%d %d %d\n",j,i,res);
}}


C  HDU 1037
大洪水,小于168的情况就输出,没有就no crash,心理素质差,太慌了,没写no crash ,搞不懂我怎么A的,不科学。
    
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#define PI acos(-1)
using namespace std;
int main()
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a<=168)printf("CRASH %d\n",a);
else if(b<=168)printf("CRASH %d\n",b);
else if(c<=168)printf("CRASH %d\n",c);
}


D  HDU 1050
过道里面搬桌子,每搬一个10分钟,有正在使用的过道则搬运延后。全场没人A,估计没人认真看题吧。用一个数组储存各个过道被经过的次数,经过最多的过道的经过次数*10为答案,注意x>y的情况。
    
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<ctype.h>
#define PI acos(-1)
using namespace std;
int main()
{
int a[210];
int n;
int x,y;
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
scanf("%d%d",&x,&y);
int tep;
if(x>y)tep=x,x=y,y=tep;
for(int k=(x+1)/2;k<=(1+y)/2;k++){
a[k]++;
}
}
sort(a,a+210);
printf("%d\n",a[209]*10);
}
 
}

E  HDU 1062
遇到空格就字符反转。
    
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#define PI acos(-1)
using namespace std;
int main()
{
int n;
char a[1010];
scanf("%d",&n);
getchar();
while(n--){
gets(a);
int i,s=0,e;
for(i=0;a[i]!='\0';i++)
if(a[i]==' '){e=i-1;
for(int k=e;k>=s;k--){
printf("%c",a[k]);
}
printf(" ");s=i+1;
}
for(int k=i-1;k>=s;k--){
printf("%c",a[k]);
}
printf("\n");
}
return 0;
}

F  HDU 1106
以前没有A的 遇5分割,并排序。
    
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#define PI acos(-1)
using namespace std;
int main()
{
char a[1010];
long b[1010];
char tep[1010];
while(~scanf("%s",a))
{
int len=strlen(a);
int s=0,e;
int k=0,kk;
memset(b,0,sizeof(b));
for(int i=0;i<=len;i++)
{
if((a[i]=='5'||a[i]=='\0')&&((a[i-1]=='5')||(a[i-1]<'0'||a[i-1]>'9'))){s++;continue;}
if(a[i]=='5'||a[i]=='\0'){
e=i-1;
for(kk=s;kk<=e;kk++){
tep[kk-s]=a[kk];
}tep[e-s+1]='\0';s=i+1;
b[k++]=atol(tep);
}}
sort(b,b+k);
for(int i=0;i<k-1;i++)
{
printf("%ld ",b[i]);
}
printf("%ld\n",b[k-1]);}
}

G  CF520A
所有字母全部出现输出YEs,否则输出nO,数组储存。
    
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<ctype.h>
#define PI acos(-1)
using namespace std;
int main()
{
int a[27];
char b[20020];
int n,i;
scanf("%d",&n);
memset(a,0,sizeof(a));
scanf("%s",b);
for(i=0;i<n;i++)
{if(isupper(b[i]))b[i]=b[i]-'A'+'a';
a[b[i]-'a']=1;}
for(i=0;i<26;i++)
if(a[i]==0){printf("NO\n");break;}
if(i==26)printf("YES\n");
 
}
 


H  CF520B
两种操作 -1和*2,从m运算到n. 分解因式,最小2的次方的指数加上各项一分解得到的二的次方项的系数和。
    
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<ctype.h>
#define PI acos(-1)
using namespace std;
int main()
{
int m,n,t;
while(~scanf("%d%d",&m,&n)){
int k,l;int res;
if(m>=n)printf("%d\n",m-n);
 
else{ for(int i=0;;i++){
if(pow(2,i)*m>=n){k=i;break;}
}
int tep=pow(2,k)*m-n;
l=0;
for(int i=k;i>=0;i--){
t=pow(2,i);
l+=tep/t;
tep%=t;
}
res=k+l;
 
printf("%d\n",res);}
}
 
}
这里有必要提一下队友的广搜的代码:
    
#include<cstdio>//申则宇
#include<queue>
using namespace std;
bool vis[20000];
 
struct node
{
int n;
int d;
node(int _n,int _d):n(_n),d(_d){};
};
 
int bfs(int p,int q)
{
int n,d;
queue<node> qe;
qe.push(node(p,0));
while(!qe.empty())
{
n=qe.front().n,d=qe.front().d;
qe.pop();
if(n==q)return d;
 
if(n>1&&vis[n-1]==0)
qe.push(node(n-1,d+1)),vis[n-1]=1;
if(n<q&&vis[n*2]==0)
qe.push(node(n*2,d+1)),vis[n*2]=1;
}
return -1;
}
 
int main()
{
int num1,num2;
scanf("%d%d",&num1,&num2);
printf("%d\n",bfs(num1,num2));
return 0;
}

I  CF520C
并没有读懂题意,WA了一发.(确实看了题解)
给碱基序列,求有最大配对值的总数。
要求最大,每个碱基的可能性都是(最多的碱基数的个数)。
给出两个我的代码,表示只能用getchar,qmod还没有朴素来得快,醉了。
   
#include<iostream>//快幂
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define MX 1000000007
long long qmod(int x,int y)
{
long long res=1;
long long t=x;
while(y){
if(y&1)res=(res*t)%MX;
y>>=1;
t=(t*t)%MX;
}
return res;
}
 
int main()
{
char s[10010];
int a[4];
int n;
while(~scanf("%d",&n)){
a[0]=a[1]=a[2]=a[3]=0;
getchar();
for(int i=0;i<n;i++){
switch(getchar()){
case'A':a[0]++;break;
case'C':a[1]++;break;
case'G':a[2]++;break;
case'T':a[3]++;break;
default:break;}
}
sort(a,a+4);
 
int cnt=0;
for (int k = 3; k >= 0; k--)
if (a[k] == a[3]) cnt++;
long long res=1;
if(cnt==1)res=1;
else {
res=qmod(cnt,n);
}
printf("%d\n",res);
}
}
    
#include<iostream>//朴素
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define MX 1000000007
 
int main()
{
char s[10010];
int a[4];
int n;
while(~scanf("%d",&n)){
a[0]=a[1]=a[2]=a[3]=0;
getchar();
for(int i=0;i<n;i++){
switch(getchar()){
case'A':a[0]++;break;
case'C':a[1]++;break;
case'G':a[2]++;break;
case'T':a[3]++;break;
default:break;}
}
sort(a,a+4);
 
int cnt=0;
for (int k = 3; k >= 0; k--)
if (a[k] == a[3]) cnt++;
long long res=1;
if(cnt==1)res=1;
else {
for(int i=0;i<n;i++)
{
res*=cnt;
res%=1000000007;
}
}
printf("%d\n",res);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值