模拟与高精度

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好像并不对)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值