招新赛+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];
}