- 无坑
- 简单模拟题目
#include<cstdio>
int main()
{
int n;
scanf("%d",&n);
int sum;
for(int i=0;;i++)
{
if(n==1)
{
sum=i;
break;
}
else if(n%2==0)
{
n=n/2;
}
else
{
n=(3*n+1)/2;
}
}
printf("%d",sum);
return 0;
}
#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
void is(int n)
{
if(n==0)
cout<<"ling";
else if(n==1)
cout<<"yi";
else if(n==2)
cout<<"er";
else if(n==3)
cout<<"san";
else if(n==4)
cout<<"si";
else if(n==5)
cout<<"wu";
else if(n==6)
cout<<"liu";
else if(n==7)
cout<<"qi";
else if(n==8)
cout<<"ba";
else if(n==9)
cout<<"jiu";
}
int main()
{
string str;
cin>>str;
int sum=0;
for(int i=0;i<str.size();i++ )
{
sum+=(str[i]-'0');
}
int test;
int k=0;
while(1)
{
test=pow(10,k);
if(sum/test==0)
break;
else
k++;
}
int aa[k];
for(int i=(k-1);i!=-1;i--)
{
aa[i]=sum%10;
sum=sum/10;
}
for(int i=0;i<k;i++)
{
if(i!=(k-1))
{
is(aa[i]);
cout<<" ";
}
else
is(aa[i]);
}
return 0;
}
//我也不知道为啥是对的,因为在0的时候,没有测试通过
一、思路和难点
- 我要通过(题目真心难懂)
(1)CSDN网友吐槽
题目真的出的是神马鬼,题意半天没看懂。。。。
起初当真是没有理解到题目的意图,最基本的想法是按照三部分条件一步一步筛选即可,但是看到第三条就有些蒙圈了。难道是编译原理,自动机?我不禁拿出纸笔画开了图,自动机,自动机。。。这思路不靠谱!OK,于是,回过头来仔细思考,好好打量下这个题目。咦,似乎有一点不同。
(2)学习
出题目的人,出完题目之后,最好找人复审一下。不然,学计算机的人,,,,出的题目,似乎有时候真的说的不像是让人能立马看懂,甚至歧义。。。。。。
二、代码
(1)部分正确的
//部分正确??
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
using namespace std;
void is(int n)
{
if(n==1)
cout<<"YES";
else
cout<<"NO";
}
int main()
{
int n;
scanf("%d",&n);
string str;
int aa[n][3];
fill(aa[0],aa[0]+n*3,0);
int out[n]={0};
for(int i=0;i<n;i++)
{
cin>>str;
for(int j=0;j<str.size() ;j++)
{
if(str[j]=='P')
aa[i][0]++;
else if(str[j]=='A')
aa[i][1]++;
else if(str[j]=='T')
aa[i][2]++;
else
aa[i][0]=-100;
}
str.clear() ;
}
for(int i=0;i<n;i++)
{
if((aa[i][0]>0)&&(aa[i][1]>0)&&(aa[i][2]>0))
out[i]=1;
else
out[i]=0;
}
for(int i=0;i<n;i++)
{
if(i!=(n-1))
{
is(out[i]);
cout<<endl;
}
else
is(out[i]);
}
return 0;
}
//部分正确??
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
using namespace std;
void is(int n)
{
if(n==1)
cout<<"YES";
else
cout<<"NO";
}
int main()
{
int n;
scanf("%d",&n);
string str;
int aa[n][3];
fill(aa[0],aa[0]+n*3,0);
int out[n]={0};
for(int i=0;i<n;i++)
{
cin>>str;
for(int j=0;j<str.size() ;j++)
{
if(str[j]=='P')
aa[i][0]++;
else if(str[j]=='A')
aa[i][1]++;
else if(str[j]=='T')
aa[i][2]++;
else
aa[i][0]=-100;
}
str.clear() ;
}
for(int i=0;i<n;i++)
{
if((aa[i][0]>0)&&(aa[i][1]>0)&&(aa[i][2]>0))
out[i]=1;
else
out[i]=0;
}
for(int i=0;i<n;i++)
{
if(i!=(n-1))
{
is(out[i]);
cout<<endl;
}
else
is(out[i]);
}
return 0;
}
//主要在于struct的构造函数怎么写
#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<vector>
using namespace std;
struct node{
string str1;
string str2;
int v;
node(string ss,string s2,int k): str1(ss),str2(s2),v(k) {}
};
int main()
{
int n;
scanf("%d",&n);
vector<node> vi;
int aa[n];
string str1,str2;
int c;
for(int i=0;i<n;i++)
{
cin>>str1;
cin>>str2;
cin>>c;
vi.push_back(node(str1,str2,c));
aa[i]=c;
}
sort(aa,aa+n);
int max,min;
max=aa[n-1];
min=aa[0];
for(int j=0;;j++)
{
if(max==vi[j].v)
{
cout<<vi[j].str1<<" "<<vi[j].str2<<endl;
break;
}
}
for(int j=0;;j++)
{
if(min==vi[j].v)
{
cout<<vi[j].str1<<" "<<vi[j].str2;
break;
}
}
return 0;
}
- 数据量少,可以用哈希
#include <bits/stdc++.h>
using namespace std;
int K;
int main()
{
while( ~scanf("%d",&K) )
{
int loop=K;
vector<int> solve(K);
while( loop-- )
{
scanf("%d",& solve[ loop ] );
}
//特例
if( 1==K )
{
printf("%d\n",solve[0] );
continue;
}
map<int,int> mp;
for( int i=0; i<solve.size(); ++i )
{
int num=solve[i];
if( 1==num )
{
mp[1]=1;
continue;
}
while( 1 )
{
if( 1==num )
{
mp[1]=1;
break;
}
if( num&1 )
{
num = (3 * num+1)/2;
mp[num]=1;
}
else
{
num/=2;
mp[num]=1;
}
}
}
vector<int> res;
for( auto num : solve )
{
if( 0==mp[num] )
{
//cout<<"num="<<num<<endl;
res.push_back( num );
}
}
sort( res.begin(), res.end() );
reverse( res.begin(), res.end() );
int Len=res.size();
for( int i=0; i<Len; ++i)
{
printf("%d%c", res[i], (i!=(Len-1) )? ' ' : '\n' );
}
}
return 0;
}
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
int a=0,b=0,c=0;
a=n/100;
n=n-a*100;
if(a!=0)
{
for(int i=0;i<a;i++)
{
printf("B");
}
}
b=n/10;
n=n-b*10;
if(b!=0)
{
for(int i=0;i<b;i++)
{
printf("S");
}
}
for(int i=1;i<=n;i++)
{
printf("%d",i);
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int aa[n];
for(int i=0;i<n;i++)
{
scanf("%d",&aa[i]);
}
int s=0;
//m为偏移量 ,j是用来保障所有数字都被遍历的,s是原始指针
for(int j=0;j<n-1;j++,s++)
{
printf("%d ",aa[(s-m+100*n)%n]) ;
}
printf("%d",aa[(s-m+100*n)%n]) ;
// printf("ss");
return 0;
}
- //注意:最后,一个单词之后输出空格,会导致『格式错误』
- 但是。我可以输出
\n
啊 - 由于PAT是单点测试
while( scanf("%s",ans)!=EOF )
//当scanf返回值不为-1时,反复读取单词- 技巧:在黑框框中手动输入时,系统并不知道什么时候到达了所谓的『文件末尾』,因为需要快捷键
- 『Ctrl+Z』然后『ente』来告诉系统到达EOF,这样系统才会结束while
#include<cstdio>
char solution[50][20];
int main()
{
char c;
int i=0;
while(~scanf("%s",solution[i]))
{
c=getchar();
if(c=='\n')
{
break;
}
++i;
}
for(int j=i;j>=0;j--)
{
if(j!=0)
{
printf("%s ",solution[j]);
}
else
{
//注意:最后,一个单词之后输出空格,会导致『格式错误』
printf("%s",solution[j]);
}
}
return 0;
}
#include<cstdio>
#include<cstring>
int test[2000+5];
int main()
{
memset(test,-1,sizeof(test));
int a,b;
int i=0;
while(~scanf("%d%d",&a,&b))
{
++i;//表示有i组
test[1+(2*(i-1))]=a;
test[2*i]=b;
}
if(test[2*i]==0)
{
i--;
}
if(i)
{
for(int j=1;j<=i;j++)
{
printf("%d %d",test[1+(2*(j-1))]*test[2*j],test[2*j]-1);
if(j!=i)
printf(" ");
}
}
else
printf("0 0");//这个题目的陷阱所在
return 0;
}
B1011 A+B 和 C
- 坑点:int+int可能会溢出int,我用的long long 解决
- 水题
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int n;
scanf("%d",&n);
int test[n][4];
long long aa;
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&test[i][0],&test[i][1],&test[i][2]);
aa=(long long )test[i][0]+(long long)test[i][1];
aa=aa-(long long)test[i][2];
if(aa>0)
test[i][3]=1;
}
for(int i=0;i<n-1;i++)
{
if(test[i][3]==1)
{
printf("Case #%d: true\n",i+1);
}
else
printf("Case #%d: false\n",i+1);
}
if(test[n-1][3]==1)
{
printf("Case #%d: true",n);
}
else
printf("Case #%d: false",n);
return 0;
}
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
using namespace std;
vector<int> one,two,four;
int five=-1;
int three=0;
int main()
{
int n;
scanf("%d",&n);
int test;
for(int i=0;i<n;i++)
{
scanf("%d",&test);
if(test%5==0)
one.push_back(test);
else if(test%5==1)
two.push_back(test);
else if(test%5==2)
three++;
else if(test%5==3)
four.push_back(test);
else
{
if(test>five)
five=test;
}
}
int a=one.size();
int sum=0;
if(a)
{
for(int i=0;i<a;i++)
{
if(one[i]%2==0)
sum+=one[i];
}
if(sum==0)
printf("N ");
else
printf("%d ",sum);
}
else
printf("N ");
a=two.size();
sum=0;
if(a)
{
for(int i=0;i<a;i++)
{
sum+=(two[i]*pow(-1,i));
}
printf("%d ",sum);
}
else
printf("N ");
if(three)
{
printf("%d ",three);
}
else
printf("N ");
a=four.size();
sum=0;
if(a)
{
double p;
for(int i=0;i<a;i++)
{
sum+=four[i];
}
p=(double)sum/(double)a;
printf("%.1f ",p);
}
else
printf("N ");
if(five>0)
{
printf("%d",five);
}
else
printf("N");
return 0;
}
#include<cstdio>
char Day[7][4]={"MON" ,"TUE","WED" ,"THU" ,"FRI" ,"SAT" ,"SUN" } ;
char one[65];
char two[65];
char three[65];
char four[65];
int is(char c)
{
if(((c-'A')>=0)&&((c-'A')<=6))
{
return c-'A';//返回星期几0-6
}
return -1;
}
int test(char c)
{
if(((c-'0')>=0)&&((c-'0')<=9))
{
return c-'0';
}
if((c-'A')>=0)
{
if((c-'A')<=13)
{
return c-'A'+10;
}
}
return -1;
}
int Draw(char c)
{
if((c-'a')>=0&&(c-'a')<=26)
{
return 1;
}
if((c-'A')>=0&&(c-'A')<=26)
{
return 1;
}
return 0;
}
int main()
{
scanf("%s%s%s%s",one,two,three,four);
int num_one=0;
int num_two=0;
int temp=0;
for(int i=0;i<60;i++)
{
// printf("#####%d\n",is(one[i]));
if(is(one[i])>-1)
{
if(is(two[i])==is(one[i]))
{
temp=i;
num_one=is(two[i]);//获得星期几 ,输出Day[num_one]
break;
}
}
}
for(int i=temp+1;i<60;i++)
{
if(test(one[i])>-1)
{
if(test(two[i])==test(one[i]))
{
num_two=test(two[i]);//获得几点,输出num_two 2个格子
// printf("%c^^^^^^\n",two[i]);
break;
}
}
}
int num_three=0;
for(int i=0;i<60;i++)
{
if(three[i]==four[i])
{
if(Draw(three[i]))
{
num_three=i;
break;
}
}
}
printf("%s %02d:%02d",Day[num_one],num_two,num_three);
return 0;
}
- 本题中,结构体中flag的设置,用于进行分类,这个『代码技巧』需要学习
- 本题中,如果全用cin和cout会超时,因为数据量很大
- 可以采用2种方法:
- 1、如果没有关闭cout和缓冲区连接,可以混用cin和printf
- 2、如果关闭了,就不能混用cin和printf,否则会出错
(1)关闭缓冲区和cout的连接
。。。测试
#include<bits/stdc++.h>
using namespace std;
int N,L,H;
struct node
{
int virtue;
int talent;
int flag;//类别
string id;
};
bool cmp(node a, node b)
{
if( a.flag!=b.flag )
{
return a.flag<b.flag;
}
else
{
int first=(a.virtue+a.talent);
int second=(b.virtue+b.talent);
if( first!=second )
{
return first>second;
}
else
{
if( a.virtue!=b.virtue )
{
return a.virtue>b.virtue;
}
else
{
return a.id<b.id;
}
}
}
}
int judge(int virtue, int talent)
{
if( virtue<L || talent<L )
{
return 0;
}
if( virtue>=H && talent>=H ) return 1;
else if( virtue>=H && talent<H ) return 2;
else if( virtue<H && talent<H && virtue>=talent ) return 3;
else return 4;
}
int main()
{
while( ~scanf("%d%d%d",&N, &L, &H) )
{
int loop=N;
vector<node> solve;
while( loop-- )
{
node temp;
cin>>temp.id>>temp.virtue>>temp.talent;
temp.flag=judge( temp.virtue, temp.talent);
if( temp.flag )
{
solve.push_back( temp );
}
}
sort( solve.begin(), solve.end(), cmp);
cout<<solve.size()<<endl;
for( auto temp: solve )
{
printf("%s %d %d\n", temp.id.c_str(), temp.virtue, temp.talent );
//cout<<temp.id<<" "<<temp.virtue<<" "<<temp.talent<<endl; //超时
}
}
return 0;
}
- 坑点:注意范围
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
long long a,b;
int one ,two;
scanf("%lld%d%lld%d",&a,&one,&b,&two);
//schar testone[10+5],testtwo[10+5];
int s=a%10;
int sumone=0;
while(a/=10)
{
if(s==one)
{
sumone++;
}
s=a%10;
}
if(s==one)
sumone++;
int ss=b%10;
int sumtwo=0;
while(b/=10)
{
if(ss==two)
{
sumtwo++;
}
ss=b%10;
}
if(ss==two)
sumtwo++;
long long int Tone=0,Ttwo=0;
for(int i=0;i<sumone;i++)
{
Tone+=(long long )one*pow(10,i);
}
for(int i=0;i<sumtwo;i++)
{
Ttwo+=(long long )two*pow(10,i);
}
// cout<<Tone<<endl;
// cout<<Ttwo<<endl;
long long cc=(long long)Tone+(long long)Ttwo;
printf("%lld",cc);
return 0;
}
格式好题。
注意格式:getchar的使用
由于scanf使用%c时会将换行符\n读入,因此需要在合适的地方用getchar吸收空格,否则会导致读入与题意不太符合——程序输入数据后闪退,基本上就是这个问题导致的。
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
using namespace std;
int test(char aa,char bb)
{
//0表示平手
//-1表 甲win
if(aa=='B'&&bb=='B')
return 0;
else if(aa=='C'&&bb=='C')
return 0;
else if(aa=='J'&&bb=='J')
return 0;
else if(aa=='B'&&bb=='C')
return -1;
else if(aa=='B'&&bb=='J')
return 1;
else if(aa=='C'&&bb=='J')
return -1;
else if(aa=='C'&&bb=='B')
return 1;
else if(aa=='J'&&bb=='B')
return -1;
else//JheC
return 1;
}
int main()
{
int n;
scanf("%d",&n);
int a[3]={0};//0胜,1平,2负
int b[3]={0};
int a_one[3]={0};//0表示B布,1表示C锤子,2表示剪刀
int b_two[3]={0};
char aa,bb;
getchar();//易错
for(int i=0;i<n;i++)
{
scanf("%c %c",&aa,&bb);
getchar();
// printf("%c %c",aa,bb);
if(test(aa,bb)==0)
{
a[1]++;
b[1]++;
}
else if(test(aa,bb)==-1)
{
a[0]++;
b[2]++;
if(aa=='B')
a_one[0]++;
else if(aa=='C')
a_one[1]++;
else
a_one[2]++;
}
else
{
b[0]++;
a[2]++;
if(bb=='B')
b_two[0]++;
else if(bb=='C')
b_two[1]++;
else
b_two[2]++;
}
}
printf("%d %d %d\n",a[0],a[1],a[2]);
printf("%d %d %d\n",b[0],b[1],b[2]);
int out=a_one[0];
int j=0;
for(int i=1;i<3;i++)
{
if(a_one[i]>out)
{
j=i;
out=a_one[i];
}
}
if(j==0)
printf("B ");
else if(j==1)
printf("C ");
else
printf("J ");
out=b_two[0];
j=0;
for(int i=1;i<3;i++)
{
if(b_two[i]>out)
{
j=i;
out=b_two[i];
}
}
if(j==0)
printf("B");
else if(j==1)
printf("C");
else
printf("J");
return 0;
}
- 坑的测试点: if( 0==n )//第1个坑的测试点,直接break,而不是输出0000-0000=0000
- 某位不足4位,高的位置要补0
找规律比如:
![B1049 数列的片段和](.\img\B1049 数列的片段和.png)
#include<bits/stdc++.h>
using namespace std;
int maxchar[4];
int minchar[4];
//填充第2个数组
void fillmin(int n)
{
minchar[3]=n%10;
n/=10;
minchar[2]=n%10;
n/=10;
minchar[1]=n%10;
n/=10;
minchar[0]=n%10;
}
//填充第一个数组
void fillmax(int a[])
{
int i=3;
while(i>=0)
{
maxchar[3-i]=a[i];
--i;
}
}
//测试是否相同
int test(int n)
{
fillmin(n);
int flag=0;
if(minchar[0]==minchar[1]==minchar[2]==minchar[3])
{
flag=1;
}
return flag;
}
//求数组对应的值
int rtnum(int a[])
{
int sum=0;
int i=3;
int count=1;
while(i>=0)
{
sum=sum+a[i]*count;
--i;
count*=10;
}
return sum;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
if(test(n))
{
///注意每个数字按4位数格式输出。啥格式,不说清楚。。要不是用0
printf("%04d - %04d = 0000\n",n,n);
}
else
{
//还有坑,,,6174
// 测试用例:
// 6174
// 对应输出应该为:
// 7641 - 1467 = 6174
do
{
fillmin(n);
sort(minchar,minchar+4);
fillmax(minchar);
n=rtnum(maxchar)-rtnum(minchar);
printf("%d%d%d%d - %d%d%d%d = %04d\n",maxchar[0],maxchar[1],maxchar[2],maxchar[3],minchar[0],minchar[1],minchar[2],minchar[3],n);
if( 0==n )//第1个坑的测试点
{
break;
}
}while(n!=6174);
}
}
//7890有问题
return 0;
}
众所周知,char型变量在计算机是按ASCII码存储的
#include<cstdio>
#include<cstring>
int solution[10]={0};
int main()
{
char temp[1000+5];
scanf("%s",temp);
int num=strlen(temp);
for(int i=0;i<num;i++)
{
solution[temp[i]-'0']++;
}
int sum=0;
for(int i=0;i<10;i++)
{
if(solution[i])
{
sum+=solution[i];
if(sum<num)
{
printf("%d:%d\n",i,solution[i]);
}
else
{
printf("%d:%d",i,solution[i]);
}
}
}
return 0;
}
- 方案和《算法笔记》差不多
#include<bits/stdc++.h>
using namespace std;
int a,b,n,len;
int demo[32];
void solve()
{
int num=a+b;
len=0;
while( 0!=(num/n) )
{
demo[len++]=num%n;
num/=n;
}
demo[len]=num%n;
}
int main()
{
while( ~scanf("%d%d%d",&a,&b,&n) )
{
solve();
while( len>=0 )
{
printf("%d",demo[len--]);
}
printf("\n");
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int solve[10];
int main()
{
memset( solve, 0, sizeof( solve) );
for(int i=0; i<10; ++i)
{
scanf("%d",&solve[i] );
}
for(int i=1; i<10; ++i)
{
if( solve[i] )
{
solve[i]--;
printf("%d",i);
break;
}
}
for(int i=0; i<10; ++i)
{
while( solve[i]-- )
{
printf("%d",i);
}
}
printf("\n");
return 0;
}
#include<cstdio>
char test[10000+5]={0};
int ppow(int a,int b)
{
int temp=a;
a=1;
while(b--)
{
a*=temp;
}
return a;
}
int main()
{
scanf("%s",test);
int E_location=0;
if(test[0]=='-')
{
printf("-");
}
for(int i=0;i<10000+5;i++)
{
if(test[i]=='E')
{
E_location=i;
break;
}
}
int num=0;//表示左边移动或者右边移动的数目
// num=(test[E_location+2]-'0')*10+(test[E_location+3]-'0');
int right=E_location+2;
while(right++)
{
if(test[right]=='\0')
{
break;
}
}
// printf("&&&&&\n");
int k=0;
for(int j=right-1;j>=E_location+2;j--)
{
// printf("%d&&&&&\n",ppow(10,k));
num=num+(test[j]-'0')*ppow(10,k);
k++;
}
//右移的
int tt=0,you;//不用补0
if(test[E_location+1]=='+')
{
if(E_location-3>=num)//不用换右边补0
{
tt=0;
you=num;
}
else
{
tt=1;
you=E_location-3;
num-=you;//num变成看右边要补0个数
}
for(int i=2;i<2+you;i++)
{
char temp=test[i+1];
test[i+1]=test[i];
test[i]=temp;
}
if(tt)
{
for(int i=1;i<E_location-1;i++)
{
printf("%c",test[i]);
}
for(int i=0;i<num;i++)
{
printf("0");
}
}
else
{
for(int i=1;i<E_location-1;i++)
{
printf("%c",test[i]);
}
if(test[E_location-1]=='.')
{
}
else
{
printf("%c",test[E_location-1]);
}
}
}
//左移的
char t_temp;
if(test[E_location+1]=='-')
{
if(0==num)
{
for(int i=1;i<=E_location-1;i++)
{
printf("%c",test[i]);
}
}
if(num>=1)
{
t_temp=test[1];
test[1]=test[2];
test[2]=t_temp;
printf("0.");
--num;
while(num--)
{
printf("0");
}
for(int i=2;i<=E_location-1;i++)
{
printf("%c",test[i]);
}
}
}
return 0;
}
- 坑点:注意,输出格式
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int a,b;
scanf("%d%d",&a,&b);
int sum=(int)round((double)(b-a)/100);
int s=sum%3600;
int one=(sum/=3600);//小时
int three=s%60;//秒钟
int two=(s/60);//fen
if(one>=10)
{
printf("%d:",one);
}
else
{
printf("0%d:",one);
}
if(two>=10)
{
printf("%d:",two);
}
else
{
printf("0%d:",two);
}
if(three>=10)
{
printf("%d",three);
}
else
{
printf("0%d",three);
}
return 0;
}
餐考代码
1)四舍五入可以用math.h中的round函数,但是由于涉及浮点数会使写法变得复杂,因此不妨直接通过判断c2-c1的后2位来判断是四舍还是勿入,以避免浮点数运算
2)时分秒的输出要保证不足2位时高位补0,
#include<bits/stdc++.h>
using namespace std;
int main()
{
int c1,c2;
scanf("%d%d",&c1,&c2);
int ans=c2-c1;
if( ans %100 >=50)
{
ans=ans/100+1;
}
else
{
ans=ans/100;
}
printf("%02d:%02d:%02d\n",ans/3600,ans%3600/60,ans%60);
return 0;
}
## 二、代码
求多少行,通项公式
Sn和
考点:模拟
坑点:n=1只输出一个符号的时候的边界,要注意
PAT和牛客都AC
```cpp
#include<bits/stdc++.h>
using namespace std;
int solution(int n)
{
int num=25;
for(;num>0;--num)
{
if(2*num*num<=n)
{
break;
}
}
return num;
}
void test(int num,char c)
{
//uploop
int up_loop=num;
int up_num=2*num-1;
//down loop
int down_loop=num-1;
int down_num=3;
//前面空格的个数
int count=0;
for( ;up_loop>0 ; )
{
for(int i=0;i<count;++i)
{
printf(" ");
}
for(int i=0;i<up_num;++i)
{
printf("%c",c);
}
printf("\n");
//下次空格
++count;
//下次符号
up_num-=2;
//还剩下的循环
--up_loop;
}
count-=2;
for( ;down_loop>0 ; )
{
for(int i=0;i<count;++i)
{
printf(" ");
}
for(int i=0;i<down_num;++i)
{
printf("%c",c);
}
printf("\n");
//下次空格
--count;
//下次符号
down_num+=2;
//还剩下的循环
--down_loop;
}
}
int main()
{
int n;
char c;
while(~scanf("%d %c",&n,&c))
{
int num=solution(n);
if(0!=num)
{
test(num,c);
printf("%d\n",n-(2*num*num-1));
}
else
{
//表示n=1
printf("%c\n",c);
printf("0\n");
}
}
return 0;
}
- 牛客上AC了,但是PAT上显示部分正确(格式错误)
其实牛客上忽略了一个东西。那就是合理的生日数目要是是0,那么就没有人名输出(坑点)
#include<bits/stdc++.h>
using namespace std;
struct person
{
char name[6];
int year;
int month;
int day;
}maxman,minman,temp;
void init_struct()
{
strcpy(maxman.name,temp.name);
maxman.year=temp.year;
maxman.month=temp.month;
maxman.day=temp.day;
strcpy(minman.name,temp.name);
minman.year=temp.year;
minman.month=temp.month;
minman.day=temp.day;
}
//好在在草稿纸上分了情况。。。
//本来以为还要考虑,闰年啥的,但是似乎,题目说的多少岁,只是简单的年限
int test(struct person aa)
{
//是否合法,合法1
if((aa.year>1814)&&(aa.year<2014))
{
return 1;
}
else if(aa.year==1814)
{
if(aa.month>9)
{
return 1;
}
else if(9==aa.month)
{
if(aa.day>=6)
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
else if(aa.year==2014)
{
if(aa.month<9)
{
return 1;
}
else if(aa.month==9)
{
if(aa.day<=6)
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
else
{
return 0;
}
}
int struct_cmp(struct person a,struct person b)
{
//比较两个合法,合理的年龄
//a比b年长则1,年轻则-1,相同则0
if(a.year>b.year)
{
return -1;
}
else if(a.year<b.year)
{
return 1;
}
else
{
if(a.month>b.month)
{
return -1;
}
else if(a.month<b.month)
{
return 1;
}
else
{
if(a.day>b.day)
{
return -1;
}
else if(a.day<b.day)
{
return 1;
}
else
{
return 0;
}
}
}
}
int main()
{
int n;
char demo[15];
while(~scanf("%d",&n))
{
int num=0;
int flag=0;
for(int i=0;i<n;++i)
{
scanf("%s%s",temp.name,demo);
sscanf(demo,"%d/%d/%d",&temp.year,&temp.month,&temp.day);
if(1==test(temp))
{
++num;
if(0==flag)
{
//第一个合法的
init_struct();
flag=1;
}
if(struct_cmp(temp,maxman)==1)
{
strcpy(maxman.name,temp.name);
maxman.year=temp.year;
maxman.month=temp.month;
maxman.day=temp.day;
}
if(struct_cmp(temp,minman)==-1)
{
strcpy(minman.name,temp.name);
minman.year=temp.year;
minman.month=temp.month;
minman.day=temp.day;
}
}
}
printf("%d %s %s\n",num,maxman.name,minman.name);
}
return 0;
}
修改后
#include<bits/stdc++.h>
using namespace std;
struct person
{
char name[6];
int year;
int month;
int day;
}maxman,minman,temp;
void init_struct()
{
strcpy(maxman.name,temp.name);
maxman.year=temp.year;
maxman.month=temp.month;
maxman.day=temp.day;
strcpy(minman.name,temp.name);
minman.year=temp.year;
minman.month=temp.month;
minman.day=temp.day;
}
//好在在草稿纸上分了情况。。。
//本来以为还要考虑,闰年啥的,但是似乎,题目说的多少岁,只是简单的年限
int test(struct person aa)
{
//是否合法,合法1
if((aa.year>1814)&&(aa.year<2014))
{
return 1;
}
else if(aa.year==1814)
{
if(aa.month>9)
{
return 1;
}
else if(9==aa.month)
{
if(aa.day>=6)
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
else if(aa.year==2014)
{
if(aa.month<9)
{
return 1;
}
else if(aa.month==9)
{
if(aa.day<=6)
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
else
{
return 0;
}
}
int struct_cmp(struct person a,struct person b)
{
//比较两个合法,合理的年龄
//a比b年长则1,年轻则-1,相同则0
if(a.year>b.year)
{
return -1;
}
else if(a.year<b.year)
{
return 1;
}
else
{
if(a.month>b.month)
{
return -1;
}
else if(a.month<b.month)
{
return 1;
}
else
{
if(a.day>b.day)
{
return -1;
}
else if(a.day<b.day)
{
return 1;
}
else
{
return 0;
}
}
}
}
int main()
{
int n;
char demo[15];
while(~scanf("%d",&n))
{
int num=0;
int flag=0;
for(int i=0;i<n;++i)
{
scanf("%s%s",temp.name,demo);
sscanf(demo,"%d/%d/%d",&temp.year,&temp.month,&temp.day);
if(1==test(temp))
{
++num;
if(0==flag)
{
//第一个合法的
init_struct();
flag=1;
}
if(struct_cmp(temp,maxman)==1)
{
strcpy(maxman.name,temp.name);
maxman.year=temp.year;
maxman.month=temp.month;
maxman.day=temp.day;
}
if(struct_cmp(temp,minman)==-1)
{
strcpy(minman.name,temp.name);
minman.year=temp.year;
minman.month=temp.month;
minman.day=temp.day;
}
}
}
//修改之处
if(0==num)
{
printf("%d\n",num);
}
else
{
printf("%d %s %s\n",num,maxman.name,minman.name);
}
}
return 0;
}
- 代码
注意,我在提交的时候,写的数组叫hash 虽然本地能过,但是 PAT和牛客后面显示编译错误,后面改为myhash 原因是:『有哪个头文件包含的太多了,有的命名和某些头文件中冲突了』
所以,以后命名不要起,我没用#include<bits/stdc++.h>
头文件的时候的
都AC
#include<bits/stdc++.h>
using namespace std;
int myhash[256]={0};
//表示是否存过,用来去重
int tag[256]={0};
int test(char c)
{
if((c>='a')&&(c<='z'))
{
//表示是小写字母
return 1;
}
else
{
//表示不是小写字母,不需转化
return 0;
}
}
void init(char aa[],int myhash[])
{
int i=0;
while(aa[i]!='\0')
{
myhash[aa[i]]=1;
++i;
}
}
int main()
{
vector<char> solution;
char one[81];
char two[81];
while(~scanf("%s%s",one,two))
{
memset(myhash,0,sizeof(myhash));
memset(tag,0,sizeof(tag));
init(two,myhash);
int i=0;
int len=strlen(one);
for(int i=0;i<len;++i)
{
if(0==myhash[one[i]])
{
// 小写-32就是大写
// printf("%c",'a'-32) ;
if(test(one[i]))
{
if(0==tag[one[i]-32])
{
solution.push_back(one[i]-32);
}
tag[one[i]-32]=1;
}
else
{
if(0==tag[one[i]])
{
solution.push_back(one[i]);
}
tag[one[i]]=1;
}
}
}
int num=solution.size();
for(int i=0;i<num;++i)
{
printf("%c",solution[i]);
}
printf("\n");
}
return 0;
}
- 暴力
- 牛客只显示超时一条,PAT不仅显示了一条超时,还显示了一条某个答案错误
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+1;
int test[maxn]={0};
int n,p;
int max2min(int num,int p)
{
//表示不OK
int flag=0;
int temp=n-1;
while(temp-num>-1)
{
if(test[temp]<=(test[temp-num]*p))
{
flag=1;
break;
}
--temp;
}
return flag;
}
int min2max(int num,int p)
{
//表示不OK
int flag=0;
int temp=0;
while(temp+num<n)
{
if(test[temp+num]<=(test[temp]*p))
{
flag=1;
break;
}
++temp;
}
return flag;
}
int main()
{
while(~scanf("%d%d",&n,&p))
{
for(int i=0;i<n;++i)
{
scanf("%d",&test[i]);
}
sort(test,test+n);
int solution=n;
//从小到大n个尝试
//从大到小n个尝试
do
{
if(1==min2max(solution,p)||1==max2min(solution,p))
{
break;
}
--solution;
}while(1);
//修正0-7,其实是8个
printf("%d\n",solution+1);
}
return 0;
}
双指针
牛客网上AC了,但PAT上显示有一个答案错误
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+1;
int test[maxn]={0};
int n,p;
int main()
{
while(~scanf("%d%d",&n,&p))
{
for(int i=0;i<n;++i)
{
scanf("%d",&test[i]);
}
sort(test,test+n);
int solution=1;
//双指针法
int i=0,j=0;
while((i<n)&&(j<n))
{
while((j<n)&&(test[j]<=(long long)(test[i]*p)))
{
solution=max(solution,j-i+1);
++j;
}
++i;
}
printf("%d\n",solution);
}
return 0;
}
下面这个却在牛客和PAT上都AC了
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100010;
int n, p, a[maxn];
int main()
{
scanf("%d%d", &n, &p);
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
}
sort(a, a+n);
int i = 0, j = 0, count = 1;
while(i < n && j < n){
while(j < n && a[j] <= (long long)a[i]*p){
count = max(count, j - i +1);
j++;
}
i++;
}
printf("%d\n", count);
return 0;
}
原因
或许是max的原因?? 也似乎没有,我改掉万能头文件 然后,还是不行
后面发现是溢出了 (long long)a[i]*p) 要先转换后乘,而不能乘完再转换,那时候溢出已经发生了。
修改
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+1;
int test[maxn]={0};
int n,p;
int main()
{
while(~scanf("%d%d",&n,&p))
{
for(int i=0;i<n;++i)
{
scanf("%d",&test[i]);
}
sort(test,test+n);
int solution=1;
//双指针法
int i=0,j=0;
while((i<n)&&(j<n))
{
while((j<n)&&(test[j]<=p*(long long)test[i]))
{
solution=max(solution,j-i+1);
++j;
}
++i;
}
printf("%d\n",solution);
}
return 0;
}
#include<cstdio>
#include<cstring>
char solution[100+1][20];
char last[11]={'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};//X的数字是88
int value[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
int isNum(char c)
{
if(((c-'0')>=0)&&((c-'0')<=9))
{
return c-'0';
}
else
{
return -1;//表示不是数字
}
}
int main()
{
int num;
scanf("%d",&num);
int test=1;//1表示通过
for(int i=0;i<num;i++)
{
scanf("%s",solution[i]);
}
int sum=0;
for(int i=0;i<num;i++)
{
sum=0;
int test_sum=1;//1表示求和了17次
for(int j=0;j<17;j++)
{
if(isNum(solution[i][j])>=0)
{
sum=sum+value[j]*isNum(solution[i][j]);
sum%=11;
}
else
{
test=0;
test_sum=0;
printf("%s\n",solution[i]);
break;
}
}
if(test_sum)
{
if((last[sum]-solution[i][17])!=0)
{
printf("%s\n",solution[i]);
test=0;
}
}
}
if(test)
{
printf("All passed");
}
return 0;
}
#include<cstdio>
#include<cstring>
const int maxn=100000+5;
int solution[maxn]={0};
int main()
{
int n;
scanf("%d",&n);
int a,b;
for(int i=0; i<n; ++i)
{
scanf("%d%d",&a,&b);
solution[a]+=b;
}
int num=1,value=solution[1];
for(int i=2 ; i<=n ; ++i)
{
if(solution[i]>value)
{
value=solution[i];
num=i;
}
}
printf("%d %d",num,value);
return 0;
}
- 题目有坑://坑点1:注意空格也可能。。。所以不能用
scanf("%s"...)
- 样例好像有错:『『话语歧义:注意:如果上档键坏掉了,那么大写的英文字母无法被打出。』』
- 比如,如果是大写字母,但是
+
坏了,但是小写字母可以打印,题目的样例却不让打印。。 - 2021.5.27记载
#include<bits/stdc++.h>
using namespace std;
string solve;
int myHash[256]={0};//0表示可以输出
int main()
{
//坑点1:注意空格也可能。。。所以不能用scanf("%s"...)
while( getline(cin,solve) )
{
for (int i = 0; i<solve.size(); ++i)
{
if( '+'==solve[i] )
{
myHash[ solve[i] ]=1;
}
else if( isupper(solve[i]) )
{
myHash[ solve[i] ]=1;
myHash[ solve[i]+32 ]=1;//小写的也不OK
}
else
{
myHash[ solve[i] ]=1;
}
}
solve.clear();
getline(cin,solve);
for (int i = 0; i<solve.size(); ++i)
{
if ( 0==myHash[ solve[i] ] )
{
//如果是大写
if( isupper(solve[i]) )
{
if( 0==myHash['+'] && 0==myHash[ solve[i]+32])
{
printf("%c",solve[i]);
}
/*
//加上下面这个就会,部分正确。。。
else if( 1==myHash['+'] && 0==myHash[ solve[i]+32])
{
printf("%c",solve[i]+32);
}
*/
}
else
{
printf("%c",solve[i]);
}
}
}
printf("\n");
memset( myHash, 0,sizeof( myHash ) );
break;
}
return 0;
}
- 技巧:整数除以2进行四舍五入的操作可以通过判断它是否是奇数来解决,以免浮点数介入。
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int n;
char str;
scanf("%d %c",&n,&str);
int numm;
if(n%2){
numm=n/2+1;
}
else
numm=n/2;
for(int i=1;i<=numm;i++)
{
if(i==1||i==numm)
{
for(int j=1;j<=n;j++)
{
printf("%c",str);
}
}
else{
printf("%c",str);
for(int j=1;j<=n-2;j++)
{
printf(" ");
}
printf("%c",str);
}
printf("\n");
}
return 0;
}
- 水题
#include<bits/stdc++.h>
using namespace std;
struct node
{
int Galleon;
int Sickle;
int Knut;
int val;
node(): val(0)
{
};
};
int main( )
{
node a,b;
while( ~scanf("%d.%d.%d %d.%d.%d", &a.Galleon, &a.Sickle, &a.Knut,
&b.Galleon, &b.Sickle, &b.Knut ) )
{
a.val= a.Galleon *17*29+ a.Sickle *29 + a.Knut;
b.val= b.Galleon *17*29+ b.Sickle *29 + b.Knut;
int temp=a.val-b.val;
if( 0==temp )
{
printf("0.0.0\n");
}
else if( temp>0 )
{
int one=temp/(17*29);
temp%=(17*29);
int two=temp/29;
temp%=29;
int three=temp;
printf("-%d.%d.%d\n", one, two, three);
}
else
{
temp=-1*temp;
int one=temp/(17*29);
temp%=(17*29);
int two=temp/29;
temp%=29;
int three=temp;
printf("%d.%d.%d\n", one, two, three);
}
}
return 0;
}
一、思路
- 格式注意
- hash
- 水题
二、代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while( ~scanf("%d",&n) )
{
map<int,int> mp;
int temp;
while( n-- )
{
scanf("%d",&temp);
mp[temp]++;
}
int search;
scanf("%d",&search);
while( search-- )
{
scanf("%d",&temp);
if( 0==search )
{
printf("%d\n",mp[temp]);
}
else
{
printf("%d ",mp[temp]);
}
}
}
return 0;
}
- 哈希水题
#include<bits/stdc++.h>
using namespace std;
static const int maxn=1e3+5;
char one[maxn],two[maxn];
int Have[256];
int Need[256];
int main()
{
while( ~scanf("%s",one) )
{
scanf("%s",two);
memset( Have, 0, sizeof( Have) );
memset( Need, 0, sizeof( Need) );
int len=strlen(one);
for(int i=0; i<len; ++i)
{
char c=one[i];
Have[c]++;
}
len=strlen(two);
for(int i=0; i<len; ++i)
{
char c=two[i];
Need[c]++;
}
int up=0;
int down=0;
int tag=0;//表示不缺
for(int i=0; i<256; ++i)
{
int temp=Have[i]-Need[i];
if( temp>=0 )
{
up+=temp;
}
else
{
down+=(-1*temp);
tag=1;//缺少
}
}
//缺少
if( tag )
{
printf("No %d\n",down);
}
else
{
printf("Yes %d\n",up );
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+1;
char test[maxn]={0};
//当前的左边的P的个数
int lleft[maxn]={0};
//当前的右边的T的个数
int rright[maxn]={0};
int main()
{
while(~scanf("%s",test))
{
int len=strlen(test);
if(len<3)
{
printf("0\n");
}
else
{
memset(lleft,0,sizeof(lleft));
memset(rright,0,sizeof(rright));
for(int i=1;i<len;++i)
{
if(test[i-1]=='P')
{
//当前的左边的P的个数
lleft[i]=lleft[i-1]+1;
}
else
{
lleft[i]=lleft[i-1];
}
}
for(int i=len-2;i>=0;--i)
{
if(test[i+1]=='T')
{
//当前的右边的T的个数
rright[i]=rright[i+1]+1;
}
else
{
rright[i]=rright[i+1];
}
}
long long sum=0;
for(int i=1;i<len;++i)
{
if(test[i]=='A')
{
sum=(sum+lleft[i]*rright[i])%1000000007;
}
}
printf("%lld\n",sum%1000000007);
}
}
return 0;
}
技巧:由于准考证是14位,可以用long long承载
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
int test[3][1000+5];
int main()
{
vector<long long> out;
int n;
scanf("%d",&n);
long long temp;
int one ,two;
for(int i=0;i<n;i++)
{
scanf("%lld%d%d",&temp,&one,&two);
out.push_back(temp);
test[1][one]=i;
test[2][one]=two;
}
int m;
scanf("%d",&m);
vector<int> aa;
int t;
for(int i=0;i<m;i++)
{
scanf("%d",&t);
aa.push_back(t);
}
for(int i=0;i<m;i++)
{
printf("%lld %d",out[test[1][aa[i]]],test[2][aa[i]]);
if(i!=(m-1))
printf("\n");
}
return 0;
}
- 用的纯C语言,原因,只是想用gets
- 技巧记忆:大写字母+' '等于小写字母
- 水题
- 坑点:只统计大小写字母,不统计
'.'
和' '
这样的字符!!!
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<ctype.h>
#define maxn 1005
char solve[maxn];
int main()
{
while( NULL!=gets(solve) )
{
int len=strlen( solve );
int myHash[256]={0};
int maxNum=-1;
for(int i=0; i<len; ++i)
{
//注意,只能是字母,不能是.
if( isalpha( solve[i]) )
{
if( islower( solve[i] ) )
{
myHash[ solve[i] ]++;
maxNum= maxNum>myHash[ solve[i] ] ? maxNum : myHash[ solve[i] ];
}
else
{
char temp=solve[i]+' ';
myHash[ temp ]++;
maxNum= maxNum>myHash[ temp ] ? maxNum : myHash[ temp ];
}
}
}
char out=0;
for(int i=0; i<256; ++i)
{
// printf("%c num=%d\n",i,myHash[i]);
if( myHash[i]==maxNum )
{
out=i;
break;
}
}
printf("%c %d\n",out,maxNum);
}
return 0;
}
- //坑点:我们只统计,6个字符,其他字符一概不看
- C++11语法
#include<bits/stdc++.h>
using namespace std;
static const int maxn=1e5;
char solve[maxn];
char rmp[6]={ 'P', 'A', 'T', 'e', 's', 't'};
map<char,int> mp;
void init()
{
int tag=0;
for( auto c : rmp )
{
mp[c]=tag;
tag++;
}
}
int main()
{
init();
while( ~scanf("%s",solve) )
{
int myHash[6]={0};
int len=strlen( solve );
for( int i=0; i<len; ++i )
{
//坑点:我们只统计,6个字符,其他字符一概不看
if( 'P'==solve[i]|| mp[ solve[i] ] )
{
myHash[ mp[ solve[i] ] ]++;
}
}
while( 1 )
{
int sumZero=0;
for(int i=0; i<6; ++i)
{
if( myHash[i] )
{
printf("%c", rmp[i]);
--myHash[i];
}
else
{
++sumZero;
}
}
if( 6==sumZero )
{
printf("\n");
break;
}
}
}
return 0;
}
- 由于范围在[0,169),所以更简单的方法是『打表』,方法二
- 教训:能不直接模拟的,不要浪费时间写模拟,能打表就打表
方法一:不是很明智的方法,直接模拟
- 坑的数据,我加注了哪一行
//最坑的数据 max
,原因是13对应是tam
而不是tam tret
- 或许也是测试数据中。
tam
对应13,却不是tam tret
对应13的原因 - 吐槽:题目中也没有说清楚,反正就是很迷。。
#include<bits/stdc++.h>
using namespace std;
map<int,string> mp;//一般版
map<int,string> carry;//进位版
map<string,int> str2mars;
void init()
{
string normal[13]={ "tret", "jan" , "feb", "mar" , "apr",
"may", "jun", "jly" , "aug", "sep", "oct", "nov", "dec" };
for(int i=0; i<13; ++i)
{
mp[i]=normal[i];
str2mars[ normal[i] ]=i;
}
string Cnormal[13]={ "tret", "tam", "hel", "maa", "huh", "tou",
"kes", "hei", "elo", "syy", "lok", "mer", "jou" };
for(int i=0; i<13; ++i)
{
carry[i]=Cnormal[i];
if( 0!=i )
{
str2mars[ Cnormal[i] ]=i;
}
}
}
int char2num(string temp)
{
string normal[13]={ "tret", "jan" , "feb", "mar" , "apr",
"may", "jun", "jly" , "aug", "sep", "oct", "nov", "dec" };
for(int i=0; i<13; ++i)
{
//这种比较方式可行
if( temp==normal[i] )
{
return i;
}
}
return str2mars[temp]*13;
}
void one(char temp[])
{
int num;
sscanf(temp,"%d",&num);
if( 0==num )
{
printf("tret\n");
return ;
}
// printf( "num=%d\n",num);
// system("pause");
//转换为13进制
int tag=1;
stack<string> st;
while( num )
{
if( tag )
{
st.push( mp[ num%13 ] );
tag=0;
}
else
{
st.push( carry[ num%13 ] );
}
num/=13;
}
tag=1;
while( !st.empty() )
{
if( tag )
{
printf("%s", st.top().c_str() );
tag=0;
}
else
{
//最坑的数据 max
if( "tret"==st.top() )
{
break;
}
else
{
printf(" %s", st.top().c_str() );
}
}
st.pop();
}
printf("\n");
}
void two( string str ,int len)
{
// printf("len=%d\n",len);
int left=0;
int right=0;
int sum=0;
while( right<=len )
{
while( !(' '==str[right] || '\0'==str[right]) )
{
++right;
}
if( right>len )
{
break;
}
string out=str.substr(left, right-left);
sum+=char2num(out);
// printf("%s add=%d\n", out.c_str(), char2num(out) );
left=right+1;//易错的地方,一定要+1
++right;//易错的地方,一定要+1
}
printf("%d\n",sum);
}
int main()
{
init();
int n;
while( ~scanf("%d",&n) )
{
//坑点:记忆要
getchar();
while( n-- )
{
char temp[100]={0};
cin.getline(temp,1000);
string str(temp);
// printf("temp:%s\n",temp);
//判断是地球人的数字吗?
if( isdigit(str[0] ) )
{
one(temp);
}
else
{
two( str , strlen( temp ) );
}
}
}
return 0;
}
方法二、打表
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int aa(int sum,int ii,int jj)
{
if(sum==ii+jj)
return 1;
else
return 0;
}
int test(int a,int one,int c,int two)
{
//输出1表示,甲输已赢(甲要喝)
//输出2表示, 。。。
//输入0,则算了
if(aa(one,a,c)>aa(two,a,c))
{
return 2;
}
else if(aa(one,a,c)<aa(two,a,c))
{
return 1;
}
else
return 0;
}
int main()
{
int n;
scanf("%d",&n);
int a,one,b,two;
int out[2]={0};
for(int i=0;i<n;i++)
{
scanf("%d%d%d%d",&a,&one,&b,&two);
if(test(a,one,b,two)==1)
{
out[0]++;
}
else if(test(a,one,b,two)==2)
{
out[1]++;
}
}
printf("%d %d",out[0],out[1]);
return 0;
}
一、思路
- hash
- 水题
二、正向迭代器版本-代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while( ~scanf("%d",&n) )
{
map<int,int> mp;
int temp,bye,num;
while( n-- )
{
scanf("%d%d%d",&temp,&bye,&num);
mp[temp]+=num;
}
map<int,int>::iterator it=mp.begin();
map<int,int>::iterator solve=it;
for(; it!=mp.end(); ++it)
{
if( (*it).second > (*solve).second )
{
solve=it;
}
}
printf("%d %d\n",(*solve).first, (*solve).second );
}
return 0;
}
三、反向迭代器版本-代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while( ~scanf("%d",&n) )
{
map<int,int> mp;
int temp,bye,num;
while( n-- )
{
scanf("%d%d%d",&temp,&bye,&num);
mp[temp]+=num;
}
//注意反向迭代器reverse_iterator
map<int,int>::reverse_iterator it=mp.rbegin();
map<int,int>::reverse_iterator solve=it;
//注意结束条件是rend(),然后注意是++不是--
for(; it!=mp.rend(); ++it)
{
if( (*it).second > (*solve).second )
{
solve=it;
}
}
printf("%d %d\n",(*solve).first, (*solve).second );
}
return 0;
}
- 本来考虑了lenA>lenB和lenA<lenB的情况
- 但是,好像,题目中要求我们将没有对齐的按照『‘0’』处理??
- 还有更好的解法:先反转字符串,然后最后再反转回去。
- 此外,我们的还可以
puts(solve)
输出
#include<bits/stdc++.h>
using namespace std;
static const int maxn=105;
char one[maxn];
char two[maxn];
char solve[maxn];
map<int,char> mp;
void init()
{
for(int i=0; i<10; ++i)
{
mp[i]=i+'0';
}
mp[10]='J';
mp[11]='Q';
mp[12]='K';
}
char demo(char a, char b, int tag)
{
int aa=a-'0';
int bb=b-'0';
if( 1==tag )
{
return mp[ (aa+bb)%13 ];
}
else
{
int temp=bb-aa;
if( temp>=0 )
{
return mp[temp];
}
else
{
return mp[temp+10];
}
}
}
int main()
{
init();
memset( solve, 0, sizeof( one ) );
memset( solve, 0, sizeof( two ) );
while( ~scanf("%s %s", one, two) )
{
memset( solve, 0, sizeof( solve ) );
int LenA=strlen(one);
int LenB=strlen(two);
//理解错题目意思???
/*int loop=LenA-LenB;
if( loop>0 )
{
while( loop-- )
{
solve[loop]=one[loop];
}
}
else if( loop<0 )
{
while( loop-- )
{
solve[loop]=two[loop];
}
}
*/
//int loop=max( LenA, LenB );
int loop,pos;
pos=loop= LenA>LenB ? LenA : LenB;
--pos;
int Lone=LenA-1;
int Ltwo=LenB-1;
int tag=1;//奇数
while( loop-- )
{
char a= Lone>=0 ? one[Lone--] : '0';
char b= Ltwo>=0 ? two[Ltwo--] : '0';
solve[pos--]=demo( a , b , tag);
tag*=(-1);
}
printf("%s\n",solve);
memset( solve, 0, sizeof( one ) );
memset( solve, 0, sizeof( two ) );
}
return 0;
}
一、思路和难点
- 精度坑
二、代码
错误思路
我把片段两两一组,组合成一个整的,,,后面发现,整的可以分成很多份啊。。。。
找规律AC
总结:其实,这些题目不难,但是我似乎编程的时候总是有个想法,要用最优的算法啥的
这样就给自己添加了很多的负担的感觉————————————————@!!!!!!!!
精度问题2
感谢 Ruihan Zheng 对测试数据的修正。
思路:
大人,时代变了!!!
这个题似乎在2020年6月17左右更改了数据和答案,所以说,包括书上的答案,很多大佬写的博客,还有我以前的代码都过不了了。主要的更改的地方是第三个测试点,我猜测主要是浮点数精度的修正。
这个题的作者是CAO, Peng,他的题很多都是需要动点小脑筋的,而不主要是书本上的知识。
通读这个题的题目,感觉蛮复杂的,但是仔细想一下,我们没有必要把每个数列片段全穷举出来。换个思路想想,把所有数列片段混合起来看,每个数共出现过多少次。
————————————————
版权声明:本文为CSDN博主「冰释的温存」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_21394327/java/article/details/106975016
- 坑点:精度
- 这是1个找数学规律的好题目
- 我写的代码中summ+=....就是列出几个数字找规律出来的
#include <cstdio>
using namespace std;
#define ll long long
ll n,summ,tmpa;
double tpda;
int main(){
scanf("%lld",&n);
for(ll i=0;i<n;++i){
scanf("%lf",&tpda);
tmpa = ((ll)(tpda*10000)+5)/10; //从结果上来看,这么做吧原来的浮点数乘以1000再转为整型
summ += tmpa * (i+1) * (n-i); //为什么要先乘以一万再加5除以十?是因为最低位会产生精度误差。
} //加五除十是为了四舍五入
printf("%lld.%02lld",summ/1000,((summ%1000)+5)/10);
return 0;
}
#include<iostream>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
long long sum=0;
long long temp;
for(int i=0;i<n;++i)
{
cin>>temp;
sum+=temp;
}
cout<<sum*(n-1)*(10+1)<<endl;
}
return 0;
}
- cin.getline(solve,maxn)
#include<bits/stdc++.h>
using namespace std;
static const int maxn=1e5+5;
char solve[maxn];
int trav( char c )
{
if( isalpha(c) )
{
if( islower(c) )
{
return c-'a'+1;
}
else
{
return c-'A'+1;
}
}
else
{
return 0;
}
}
int main()
{
while( cin.getline(solve,maxn) )
{
int sum=0;
for( auto c : solve )
{
sum+=trav(c);
}
if( 0==sum )
{
printf("0 0\n");
}
else
{
int one=0;
int ALL=0;
while( sum )
{
++ALL;
int tag=sum%2;
if( tag )
{
++one;
}
sum/=2;
}
printf("%d %d\n",ALL-one, one);
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int test[101][102];
int aa[2][101];
int n,m;
void kk()
{
for(int i=0;i<n;++i)
{
test[i][101]=0;
for(int j=0;j<m;++j)
{
if(test[i][j]==aa[1][j])
{
test[i][101]+=aa[0][j];
}
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<m;++i)
{
scanf("%d",&aa[0][i]);
}
for(int i=0;i<m;++i)
{
scanf("%d",&aa[1][i]);
}
for(int i=0;i<n;++i)
{
for(int j=0;j<m;++j)
{
scanf("%d",&test[i][j]);
}
}
kk();
for(int i=0;i<n;++i)
{
printf("%d\n",test[i][101]);
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const double eps=10e-9;
int main()
{
int n;
double a,b;
double c=0,d=0;
while(~scanf("%d",&n))
{
for(int i=0;i<n;++i)
{
scanf("%lf%lf",&a,&b);
if(sqrt(a*a+b*b)>sqrt(c*c+d*d))
{
c=a;
d=b;
}
}
printf("%.2f\n",sqrt(c*c+d*d));
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int tag[40]={0};
int demo(int a)
{
int su=0;
while(a!=0)
{
su+=a%10;
a/=10;
}
return su;
}
int main()
{
int n;
int temp;
while(~scanf("%d",&n))
{
for(int i=0;i<n;++i)
{
scanf("%d",&temp);
tag[demo(temp)]=1;
}
int num=0;
for(int i=0;i<37;++i)
{
if(tag[i]==1)
{
++num;
}
}
printf("%d\n",num);
for(int i=0;i<37;++i)
{
if(tag[i]==1)
{
if(num==1)
{
printf("%d",i);
}
else
{
printf("%d ",i);
}
--num;
}
}
memset(tag,0,sizeof(tag));
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
//第2行表示出现了
int tag[100005][2]={0};
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(tag,-1,sizeof(tag));
for(int i=0;i<n;++i)
{
char test[6],kk[6];
int a=0,b=0;
scanf("%s%s",test,kk);
int quan=1;
for(int i=4;i>=0;--i)
{
a=a+(test[i]-'0')*quan;
b=b+(kk[i]-'0')*quan;
quan*=10;
}
tag[a][0]=b;
tag[b][0]=a;
}
int m;
scanf("%d",&m);
for(int i=0;i<m;++i)
{
int k;
scanf("%d",&k);
tag[k][1]=1;
}
int num=0;
for(int i=0;i<100001;++i)
{
if((tag[i][1]==1)&&(tag[tag[i][0]][1]!=1))
{
++num;
}
}
printf("%d\n",num);
for(int i=0;i<100001;++i)
{
if((tag[i][1]==1)&&(tag[tag[i][0]][1]!=1))
{
if(num==1)
{
printf("%05d",i);
break;
}
else
{
printf("%05d ",i);
}
--num;
}
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int test[502][502];
int main()
{
int m,n;
while(~scanf("%d%d",&m,&n))
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
scanf("%d",&test[i][j]);
}
}
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if(test[i][j]>=a&&test[i][j]<=b)
{
test[i][j]=c;
}
}
}
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if(j!=n-1)
{
printf("%03d ",test[i][j]);
}
else
{
printf("%03d",test[i][j]);
}
}
if(i!=m-1)
{
printf("\n");
}
}
}
return 0;
}
#include<stdio.h>
#include<string.h>
char aa[1000];
int test(char aa[],char bb[])
{
if(strlen(aa)!=strlen(bb))
{
return 0;
}
int i=0;
for(;i<strlen(bb);++i)
{
//字符比较似乎要这样
if((aa[i]-'\0')!=(bb[i]-'\0'))
{
return 0;
}
}
//匹配
return 1;
}
int main()
{
char bb[22];
int n;
scanf("%s%d",bb,&n);
getchar();
while(1)
{
//似乎坑,在这里,密码
gets(aa);
// getchar();
if(strlen(aa)==1&&aa[0]=='#')
{
break;
}
if(n!=1)
{
if(test(aa,bb))
{
printf("Welcome in\n");
break;
}
else
{
printf("Wrong password: %s\n",aa);
n--;
}
}
else
{
if(test(aa,bb))
{
printf("Welcome in\n");
break;
}
else
{
printf("Wrong password: %s\n",aa);
n--;
printf("Account locked\n");
break;
}
}
}
return 0;
}
- 考点:哈希
#include<bits/stdc++.h>
using namespace std;
int n,m;
int main()
{
while( ~scanf("%d%d",&n,&m) )
{
map<string,int> mp;
while( m-- )
{
char temp[6];
scanf("%s",temp);
string str=temp;
mp[str]=1;
}
int sumHuman=0;
int something=0;
while( n-- )
{
char name[6];
int num;
scanf("%s %d",name ,&num);
int tag=0;//这个学生没有被收缴
queue<string> solve;
while( num-- )
{
char str[6];
scanf("%s",str);
string search=str;
if( 1==mp[search] )
{
++something;
tag=1;
solve.push( search );
}
}
if( tag )
{
++sumHuman;
printf("%s:",name);
while( !solve.empty() )
{
printf(" %s", solve.front().c_str() );
solve.pop();
}
printf("\n");
}
}
printf("%d %d\n", sumHuman, something);
}
return 0;
}
- %c的时候,要注意getchar,否则会运行超时
- 水题
#include<bits/stdc++.h>
using namespace std;
int n;
map<char,int> mp;
void init()
{
mp['A']=1;
mp['B']=2;
mp['C']=3;
mp['D']=4;
}
int main()
{
init();
while( ~scanf("%d",&n) )
{
char solve[9];
while( n-- )
{
getchar();//不写这个,显然会运行超时
scanf("%c-%c %c-%c %c-%c %c-%c",
&solve[1], &solve[2], &solve[3], &solve[4],
&solve[5], &solve[6], &solve[7], &solve[8]);
for(int i=2; i<=8; i+=2 )
{
if( 'T'==solve[i] )
{
printf("%d", mp[solve[i-1] ] );
}
}
}
printf("\n");
}
return 0;
}
- 排序水题
- 深刻理解:数据多而麻烦,用结构体封装
#include<bits/stdc++.h>
using namespace std;
int n;
struct node
{
char name[6];
int val;
};
bool cmp(node a, node b)
{
return a.val<b.val;
}
int main(int argc, char const *argv[])
{
while( ~scanf("%d",&n) )
{
int save=n;
vector<node> solve(n);
while( n-- )
{
int a,b;
scanf("%s %d %d\n", solve[n].name, &a, &b);
solve[n].val=a*a+b*b;
}
sort( solve.begin(), solve.end() , cmp);
printf("%s %s\n", solve[0].name, solve[save-1].name );
}
return 0;
}
一、思路
-
题目有坑:
- 1、输出差值大于0的(可以理解)
- 2、输出出现次数大于1的(题目文字描述的不是这个意思,但是样例是这个意思,先前还以为这个题目出错了)
-
水题
二、反向迭代器版本-代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while( ~scanf("%d",&n) )
{
map<int,int> mp;
int cur=1;
int temp;
while( n-- )
{
scanf("%d",&temp);
mp[ abs(temp-cur) ]++;
++cur;
}
//反向迭代器版本
map<int,int>::reverse_iterator it=mp.rbegin();
for(; it!=mp.rend(); ++it)
{
//这个题目的坑的地方,就是要至少2个
if( (*it).second>1 )
{
printf("%d %d\n",(*it).first, (*it).second);
}
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int main()
{
char test[12];
int a,b;
while(~scanf("%d%d",&a,&b))
{
int temp=a*b;
sprintf(test,"%d",temp);
int len=strlen(test);
int flag=1;
while(len--)
{
if(flag&&test[len]=='0')
{
//题目没说清,100反着怎么来,,,
continue;
}
else
{
printf("%c",test[len]);
flag=0;
}
}
printf("\n");
}
return 0;
}
- 打表水题
#include<bits/stdc++.h>
using namespace std;
static const int maxn=1e5;
bool myHash[maxn]={0};
int solve[10000+5]={0};
//准备打表
void init()
{
myHash[0]=true;//n==1的时候已经有过这个数字
solve[0]=0;
solve[1]=1;
for(int i=2; i<10001; ++i)
{
int num=i/2+i/3+i/5;
if( false==myHash[num] )
{
solve[i]=solve[i-1]+1;
myHash[num]=true;
}
else
{
solve[i]=solve[i-1];
}
}
}
int main()
{
init();
int n;
while( ~scanf("%d",&n) )
{
printf("%d\n",solve[n]);
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int test(int n,int num)
{
char cc[5];
sprintf(cc,"%d",num);
int temp=n*num*num;
char kk[11];
sprintf(kk,"%d",temp);
int flag=1;
int len_cc=strlen(cc);
int len_kk=strlen(kk);
while(len_cc--)
{
if(cc[len_cc]!=kk[--len_kk])
{
flag=0;
break;
}
}
return flag;
}
int main()
{
int m;
while(~scanf("%d",&m))
{
for(int i=0;i<m;++i)
{
int num;
scanf("%d",&num);
int flag=0;
for(int j=0;j<10;++j)
{
if(test(j,num))
{
flag=1;
printf("%d %d\n",j,j*num*num);
break;
}
}
if(0==flag)
{
printf("No\n");
}
}
}
return 0;
}
#include<stdio.h>
#include<string.h>
char a[1000005];
char b[1000005];
int h_hash[256]={0};
int main()
{
//PAT中想要用gets只能C语言
while(NULL!=gets(a))
{
gets(b);
memset(h_hash,0,sizeof(h_hash));
int len_a=strlen(a);
int len_b=strlen(b);
int i=0;
for(;i<len_a;++i)
{
if(0==h_hash[a[i]])
{
printf("%c",a[i]);
h_hash[a[i]]=1;
}
}
for(i=0;i<len_b;++i)
{
if(0==h_hash[b[i]])
{
printf("%c",b[i]);
h_hash[b[i]]=1;
}
}
printf("\n");
}
return 0;
}