Bootstrap

10.25 招新赛+week1

招新赛+week 1

招新赛补题

7-5 排列
  • 此题和输入的p值没有关系

    以k=3为例,第一次最多把3个数变成m,往后每次最多变动2个数

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,k;
	cin>>n>>k;
	for(int i=0;i<n;i++)
	{
		char a;
		cin>>a;
	}
	int ans=1;
	if((n-k)%(k-1)==0) ans+=(n-k)/(k-1);
	else ans+=(n-k)/(k-1)+1;
	cout<<ans<<endl;
	return 0;
}
7-6 小步点

法一:直接套5个for循环(数据不大的情况下可以尝试一下暴力…

法二:给定一个图,寻找最短哈密顿路径(图还没学,没看懂,先放着

7-7 原神生日会*
  • 已给空位和派蒙,由于派蒙和谁坐都行,所以座位被分割成若干段连续的的空位

​ 若空位为2x个(偶数个),能坐x个男生和x个女生

​ 若空位为2x+1个(奇数个),能坐x个男生和x个女生,在加一个男生或一个女生

  • 另外注意:.P…PP.P. 末尾的.没有P隔断,需要再加一次判断
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,a,b;
	cin>>n>>a>>b;
	string s;
	cin>>s;
	int flag=0,flag2=0;
	int c=0,d=0;
	for(int i=0;i<s.length();++i)
	{
		if(s[i]=='.')
		flag++;
		else
		{
			if(flag%2==0)
			{
				c+=flag/2;
				d+=flag/2;
			}
			else
			{
				c+=flag/2;
				d+=flag/2;
				flag2++;
			}
			flag=0;
		}
	}
	if(flag!=0)
	{
		if(flag%2==0)
			{
				c+=flag/2;
				d+=flag/2;
			}
			else
			{
				c+=flag/2;
				d+=flag/2;
				flag2++;
			}
	}
	if(a>c)
	{
		if(a>c+flag2)
		a=c+flag2;
		else
		flag2-=a-c;
	}
	if(b>d)
	b=d+flag2;
	cout<<a+b<<endl;
	return 0;
 } 
7-8 漏字文*
  • 用到了双指针

  • 写的时候有个误区:一定要把判断的字符串用个东西存出来。其实没必要,只需要记录有没加或减少字母种类和长度变化

  • 为什么得到全字文要从左边删单词?从l开头的最长漏字文已经记录过了,应当往后找

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int sum[205]={0};
string s[maxn];
int n,ans=0,now=0,cnt=0;
//now表示所选段的长度
//cnt表示字母种类 
void modify(string s1, int x) //x为1的时候加一个单词,为-1的时候删
{
	for(int i=0;i<s1.length();++i)
	{
		if(sum[s1[i]]==0&&x>0)++cnt;//新字母 种类加一
		sum[s1[i]]+=x;
		if(sum[s1[i]]==0&&x<0) --cnt; //删掉最后一个该字母 种类减一
		
	}
 } 
int main()
{
	int l=1,r=0;//双指针
	cin>>n; 
	for(int i=1;i<=n;i++)
	cin>>s[i];
	while(r<n)
	{
		++r;
		modify(s[r],1);
		now+=s[r].length();
		while(cnt==26)
		{
			modify(s[l],-1);//全字文时删左边 
			now-=s[l].length();
			++l; 
		}
		ans=max(now,ans);
	}
	cout<<ans<<endl;
	return 0;
}

week 1

7-2 高精度加法

Tips:输入用string存,再用int数组存每一位,每一位分别相加

#include<bits/stdc++.h>
using namespace std;
int maxn=5001;
int main()
{
	string s1,s2;
	int a[maxn],b[maxn];
	cin>>s1>>s2;
	int len1=s1.length();
	int len2=s2.length();
	int len=max(len1,len2);
	
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	
	for(int i=0;i<len1;i++)
	a[len1-i-1]=(int)(s1[i]-'0');
	for(int i=0;i<len2;i++)
	{
		b[len2-i-1]=(int)(s2[i]-'0');
	}
		
	for(int i=0;i<len-1;i++)
	{
		a[i]=a[i]+b[i];
		if(a[i]>=10)
		{
			a[i+1]+=a[i]/10;
			a[i]%=10;
		}
	}
	a[len-1]+=b[len-1];
	if(a[len-1]>=10)
	{
		a[len]+=a[len-1]/10;
		a[len-1]%=10;
		len++;
	}
	for(int i=len-1;i>=0;i--)
	cout<<a[i];
	return 0;
 } 
7-3 高精度求累加和
  • 高斯公式:(首+尾)*项数/2
    • 高精度乘法:如134*135,两个for循环,先用134乘5,再乘3,再乘,最后相加。
    • 高精度除法:注意去掉先导0
#include<bits/stdc++.h>
using namespace std;
int a[101],b[999999],c[999999];
int len=0,lenb=0,lenc=0;
void divi2()
{
	for(int i=lenc-1;i>=0;i--)
	{
		if(c[i]/2<1)
		{
			c[i-1]+=c[i]*10;
			lenb++;
		}
		else
		{
			b[lenb]=c[i]/2;
			c[i-1]+=c[i]%2*10;
			lenb++;
		}
	}	
}
void muti()
{
	for(int i=0;i<len;i++)
	{
		lenc=i;
		for(int j=0;j<len;j++)
		{
			if(i==0)
			c[lenc]+=a[j]*(a[i]+1);
			else
			c[lenc]+=a[j]*a[i];		
			if(c[lenc]>=10)
			{
				c[lenc+1]+=c[lenc]/10;
				c[lenc]%=10;
			}
			lenc++;
		}
	}
}
int main()
{
	string n;
	cin>>n;

	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	len=n.length();

	for(int i=0;i<len;i++)
	a[len-i-1]=(int)(n[i]-'0');
	
	muti();
	divi2();
	
	int j=0;
	for(;j<lenb;j++)
	{
		if(b[j]!=0)
		break;
	}
	
	for(int i=j;i<lenb;i++)
	cout<<b[i];
	
 } 
;