P1042
如果一局比赛刚开始,则此时比分为 0 比 0。直到分差大于或者等于 2,才一局结束。
如果1分了,但分差拉不开,还要继续比
#include<iostream>
#include<cmath>
using namespace std;
int p,cnt[1000001];char ch;
void shu(int h)
{
int a=0,b=0;
for(int i=0;i<p;i++)
{
if(cnt[i]=='W') a++;
if(cnt[i]=='L') b++;
if((a>=h||b>=h)&&abs(a-b)>=2)
{cout<<a<<':'<<b<<endl;
a=b=0;
}
}
cout<<a<<':'<<b<<endl;
}
int main()
{
while(cin>>ch&&ch!='E')
{
if(ch=='W'||ch=='L')
cnt[p++]=ch;
}
shu(11);
cout<<endl;
shu(21);
}
先输入,用数组存下来
然后分两种进制进入函数
分别根据输入的字母来记录数字
如果大于11||21并且相差2的时候输出
P1563
用数组,用取余(左右方向要注意)
#include<bits/stdc++.h>
using namespace std;
struct node
{
int head;
string name;
}a[100005];
int n,m,x,y;
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>a[i].head>>a[i].name;
}
int now=0;
for(int i=1;i<=m;i++)
{
cin>>x>>y;
if(a[now].head==0&&x==0)now=(now+n-y)%n;
else if(a[now].head==0&&x==1)now=(now+y)%n;
else if(a[now].head==1&&x==0)now=(now+y)%n;
else if(a[now].head==1&&x==1)now=(now+n-y)%n;
}
cout<<a[now].name<<endl;
return 0;
}
确定正反,然后算出啦对应的数组序列,记得用取余
P1601
高精度
加法:作为字符串输入(得到字符串长度
转化成对应的数字数组,注意字符串的第一个是最高位,所以其实是数字序列的最后一位
最高位是a,b的最大的+1
开始搞c,先单纯的计算,然后除10,然后进位,然后取余
记得删除前导零
输出
#include<bits/stdc++.h>
using namespace std;
char s1[505],s2[505];
int a[505],b[505],c[505];
int main()
{
int la,lb,lc;
cin>>s1;
cin>>s2;
la=strlen(s1);
lb=strlen(s2);
for(int i=0;i<la;i++)//转为数字,且字符转置
a[la-i]=s1[i]-'0';
for(int i=0;i<lb;i++)
a[lb-i]=s2[i]-'0';
lc=max(la,lb)+1;
for(int i;i<=lc;i++ )
{
c[i]+=a[i]+b[i];
c[i+1]=c[i]/10;
c[i]=c[i]%10;
}
if(c[lc]==0&&lc>0)lc--;
for (int i=lc;i>0;i--)
cout<<c[i];
return 0;
}
高精度减法
先比较两个的的大小
how:先比较长度,长度相同的时候其实是可以直接比s1,s2的哦,做交换,字符串和长度都要
然后转化为数字数组
然后相减
如果小于零,借10,下一位-1
然后给c
长度是la,删除前导零
```#include<iostream>
#include<cstring>
using namespace std;
string s1,s2;
int a[100000000],b[10000000],c[100000000],la,lb,flag=0;
int main()
{
cin>>s1>>s2;
la=s1.length() ;
lb=s2.length() ;
if(la<lb||la==lb&&s1<s2)
{
flag=1;
swap(s1,s2);
swap(la,lb);
}
for(int i=0;i<la;i++)到底是哪一位和哪一位
{
a[la-i]=s1[i]-'0';
}
for(int i=0;i<lb;i++)
{
b[lb-i]=s2[i]-'0';
}
for(int i=1;i<=la;i++)
{
if(a[i]-b[i]<0)
{ a[i]+=10;
a[i+1]--;
}
c[i]=a[i]-b[i];
}
while(c[la]==0&&la>1)
{la--;
}
if(flag==1)
{cout<<"-";
}
for(int i=la;i>0;i--)
{
cout<<c[i];
}
return 0;
}
高精度乘法(高精度乘以高精度)
求出来对应的
记住c[i+j-1]+=a[i]*b[j]
然后一样的取余,然后相除
#include<iostream>
#include<cstring>
using namespace std;
string s1,s2;
int a[2000001],b[20000001],c[2000001],la,lb,lc;
int main()
{
cin>>s1>>s2;
la=s1.length() ;
lb=s2.length() ;
for(int i=0;i<la;i++)
{
a[la-i]=s1[i]-'0';
}
for(int i=0;i<=lb;i++)
{
b[lb-i]=s2[i]-'0';
}
for(int i=1;i<=la;i++)
{
for(int j=1;j<=lb;j++)
{
c[i+j-1]+=a[i]*b[j];
c[i+j]+=c[i+j-1]/10;
c[i+j-1]%=10;
}
}
lc=la+lb;
while(c[lc]==0&&lc>1)/1111111
{
lc--;
}
for(int i=lc;i>0;i--)
cout<<c[i];
return 0;
}
高精度乘以低精度
(P1009为例求阶乘之和)1591会更通透,人家那个是边走便开辟,这里的因为给定了,所以可以直接用100
#include<iostream>
using namespace std;
int main()
{ int m,i,j,a[1002]={0},b[1002]={0};
cin>>m;
a[0]=b[0]=1;
for(i=2;i<=m;i++)
{
for(j=0;j<100;j++)
{
a[j]*=i;
}
for(j=0;j<100;j++)
{
if(a[j]>9)
// while(a[j]>0)
{
a[j+1]+=a[j]/10;
a[j]%=10;
}
}
for( j=0;j<100;j++)
{
b[j]+=a[j];
if(b[j]>=10)
{
b[j+1]+=b[j]/10;
b[j]%=10;
}
}
}
for( i=100;i>=0&&b[i]==0;i--);
for(j=i;j>=0;j--)
{
cout<<b[j];
}
return 0;
}
这个就用低精度的数字去和高精度的数组每一位相乘
然后就去看每一位上面有没有>9的,有的话就进位,记得是+=,因为人家本身就有,然后自己取余,然后是要求和嘛,所以就算出来有一个加一下,高精度加法
循环的数量就是加数的数目
int main()
{ int m,i,j,a[1002]={0},b[1002]={0};
cin>>m;
a[0]=b[0]=1;
for(i=2;i<=m;i++)
{
for(j=0;j<100;j++)
{
a[j]*=i;
}
for(j=0;j<100;j++)
{
if(a[j]>9)
// while(a[j]>0)
{
a[j+1]+=a[j]/10;
a[j]%=10;
}
}
for( j=0;j<100;j++)
{
b[j]+=a[j];
if(b[j]>=10)
{
b[j+1]+=b[j]/10;
b[j]%=10;
}
}
}
for( i=100;i>=0&&b[i]==0;i--);
for(j=i;j>=0;j--)
{
cout<<b[j];
}
return 0;
}
P4924
这个其实就是掌握逆时针顺时针计算就好啦,就根据对于中心位置的变换
#include<iostream>
using namespace std;
int x[501],y[501],b[501][501],a[501][501],n,m,r[501],fx[501],k;
void bianhua(int i)
{
for(int xx=x[i]-r[i];xx<=x[i]+r[i];xx++)
{
for(int yy=y[i]-r[i];yy<=y[i]+r[i];yy++)
{
if(!fx[i])
b[x[i]+yy-y[i]][y[i]-xx+x[i]]=a[xx][yy];
else
b[x[i]+y[i]-yy][y[i]+xx-x[i]]=a[xx][yy];
}
}
for(int xx=x[i]-r[i];xx<=x[i]+r[i];xx++)
{
for(int yy=y[i]-r[i];yy<=y[i]+r[i];yy++)
{
a[xx][yy]=b[xx][yy];
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>x[i]>>y[i]>>r[i]>>fx[i];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j]=++k;
}
}
for(int i=1;i<=m;i++)
{
bianhua(i);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
耐心一点就好了
P1518
就是一个bfs了,转换方向
#include<iostream>
using namespace std;
int xx[]={-1,0,1,0};
int yy[]={0,1,0,-1};
char a[12][12];
long long int zt[19900000]={0},nx,ny,fx,fy,ff,cf,nt,t;
int main()
{
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
cin>>a[i][j];
if(a[i][j]=='C')
{
nx=i;
ny=j;
}
if(a[i][j]=='F')
{
fx=i;
fy=j;
}
}
}
while(1)
{
if(nx==fx&&ny==fy)
{
cout<<t;
return 0;
}
nt=fx+fy*10+nx*100+ny*1000+ff*10000+cf*40000;
if(zt[nt])
{
cout<<0;
return 0;
}
zt[nt]=1;
if(fx+xx[ff]<0||fx+xx[ff]>=10||fy+yy[ff]<0||fy+yy[ff]>=10||a[fx+xx[ff]][fy+yy[ff]]=='*')
ff=(ff+1)%4;
else
{fx=fx+xx[ff];fy=fy+yy[ff];
}
if(nx+xx[cf]<0||nx+xx[cf]>=10||ny+yy[cf]<0||ny+yy[cf]>=10||a[nx+xx[cf]][ny+yy[cf]]=='*')
cf=(cf+1)%4;
else
{nx=nx+xx[cf];ny=ny+yy[cf];
}
t++;
}
return 0;
}
还有点哈希的感觉,就创造一个特有的让他能够独特性表现出来,通过比较这两个数字来比较这两个东西,就是先移动,然后到边界切换移动方向,切换方向,不切换,都要记得加时间,直到他们相同
P1098
一道非常复杂但其实细细想来没有什么东西的题目
首先要知道,并不是所有的都是要展开的,减号两侧要同为小写字母 或者数字,并且有ascll顺序
qs:什么时候去做这个判断?
当遇到负号的时候
qs:判断的目的是什么?
判断它要不要进入到这个最后输出的vector里面
在这个筛选的前提之下,进入真正的展开
p1: 为三的时候都填充星号
其他的都是针对字母类型的
p2: 填充字符的重复个数,注意,重复之前可能是要逆序的,所以可以先放在一边
p3: 是否逆序
其他注意事项: 我觉得应该放在前面写,几个特殊点的判断
ok:所以在真正的展开里面,先对特殊的其他事项做判断
然后对p1==3情况
然后再分成是字母的和是数字的
数字的里面先判断p3,也就是要不要变化顺序,不要变化的话,直接玩p2,循环里面套循环来完成入数组,是的话,其实也就是第一重循环顺序改一下而已
字母的里面先判断p1,p1内部判断p3,p3里面嵌套p2
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int p1,p2,p3;
vector<char>mm;
int main()
{
string s;
cin>>p1>>p2>>p3>>s;
for(int i=0;i<=s.size();i++)
{
if(s[i]!='-')mm.push_back(s[i]);
else if((i==0||i==s.size()-1)&&s[i]=='-') mm.push_back('-');
else if(s[i]=='-'&&(s[i-1]=='-'||s[i+1]=='-'))mm.push_back('-');
else if(s[i]=='-')
{
if(s[i-1]>=s[i+1]||(s[i-1]<58&&s[i+1]>96)) mm.push_back('-');
else if(s[i+1]==s[i-1]+1)continue;
if(p1==3)
{
for(int k=1;k<=(s[i+1]-s[i-1]-1)*p2;k++) mm.push_back('*');
}
else if(s[i+1]<=57&&s[i+1]>=48&&s[i-1]<=57&&s[i-1]>=48)///0-9
{
if(p3==1)
for(int k=s[i-1]+1;k<=s[i+1]-1;k++)
{
for(int i=1;i<=p2;i++)
mm.push_back((char)k);//插入极妙
}
if(p3==2)
for(int k=s[i+1]-1;k>=s[i-1]+1;k--)
{
for(int i=1;i<=p2;i++)
mm.push_back((char)k);
}
}
else if(s[i+1]<=122&&s[i+1]>=97&&s[i-1]<=122&&s[i-1]>=97)
{
if(p1==1)
{
if(p3==1)
for(int k=s[i-1]+1;k<=s[i+1]-1;k++)
{
for(int i=1;i<=p2;i++)
mm.push_back((char)k);
}
if(p3==2)
for(int k=s[i+1]-1;k>=s[i-1]+1;k--)
{
for(int i=1;i<=p2;i++)
mm.push_back((char)k);
}
}
if(p1==2)
{
if(p3==1)
for(int k=s[i-1]+1;k<=s[i+1]-1;k++)
{
for(int i=1;i<=p2;i++)
mm.push_back((char)(k-32));
}
if(p3==2)
for(int k=s[i+1]-1;k>=s[i-1]+1;k--)
{
for(int i=1;i<=p2;i++)
mm.push_back((char)(k-32));
}
}
}
}
}
for(int i=0;i<mm.size();i++)
cout<<mm[i];
return 0;
}
P1067
其实就是构造出一个数组出来,比较麻烦的就是0吧,应该直接continue就可以了吧
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
int n,a;
cin>>n;
for(int i=n;i>=0;i--)
{
cin>>a;
if(a)
{
if(i!=n&&a>0) cout<<"+";
if(abs(a)>1||i==0)cout<<a;
if(a==-1&&i)cout<<"-";
if(i>1)cout<<"x^"<<i;
if(i==1)cout<<"x";
}
}
}
嗯,连continue都没有,反正有for循环,if不成立就结束掉
但是即使if成立了,就还是有几个特殊的,比如1,-1
P1591
噫好,高精度乘单精度,我最讨厌的东西
先解决n!
for循环里面以n为界限
每一次都是把我有的这个数组每一位都乘上这个数字+jw,然后正常的进行进位更新和取余,从小到大嘛,进位有了就有了
然后最后一个循环下来,这个后面的每一位都正常了,但是前面的呢,积累下来的进位可能已经不止是个一位数了,所以用一个while循环,把前面的开辟出来
当下一轮循环的时候,p要改变
#include<iostream>
using namespace std;
int t,o,a[100000]={0},jw;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>t>>o;
int k,p=1;
a[1]=1;
for(int j=2;j<=t;j++)
{ jw=0;
for(k=1;k<=p;k++)
{
a[k]=a[k]*j+jw;
jw=a[k]/10;
a[k]%=10;
}
while(jw>0)
{
a[k]=jw%10;
jw/=10;
k++;
}
p=k-1;
}
long long sum=0;
for(i=p;i>=1;i--)
{
if(a[i]==o)
sum++;
}
cout<<sum<<endl;
}
return 0;
}
P1249这个好像是有一个常识的:就是越多最后的乘积越大
用贪心从2开始逐渐增加(ans),直到累加到大于n,再把n-ans删除掉(emm好像并不对)