有看一些新算法 但是练习随缘 比赛没打到就不写是这样的(
Educational Codeforces Round 163 [Rated for Div. 2]
打的最爽的一场 猛猛上分 超水的Div2
A.Special Characters
输出一个长度为n的所有字符左右两边都恰好只有一个字符与其相等的字符串
闭着眼睛AABBCCDDEE...就行了
#include <iostream>
#include <string>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
if(n%2!=0)
{
printf("NO\n");
}
else
{
printf("YES\n");
char s[n+10];
char tmp='A';
n/=2;
for(int i=0;i<n;i++)
{
s[2*i]=tmp;
s[2*i+1]=tmp;
if(tmp<'Z')
tmp++;
else
tmp='A';
}
for(int i=0;i<=2*n-1;i++)
printf("%c",s[i]);
printf("\n");
}
}
return 0;
}
B. Array Fix
给一个数组 大于10的数都可以随便拆开 问能不能拆到最后出来一个单调递增的数组
其实根本不需要用链表啥的模拟插入,从右往左遍历,遇到不满足题意的留他的十位数把原来的替换掉就行,因为个位已经不重要了,然后小于十且不满足题意就愉快送走就行
#include <iostream>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int a[200]={0};
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=n-2;i>=0;i--)
{
if(a[i]>a[i+1])
{
if(a[i]<10)
goto error;
else
{
if(a[i]%10<a[i]/10)
goto error;
else if(a[i]%10>a[i+1])
goto error;
else
a[i]=a[i]/10;
}
}
}
printf("YES\n");
continue;
error:
printf("NO\n");
}
return 0;
}
C. Arrow Path
BFS板子题,当天下午刚看完BFS晚上就来一道题练手,Codeforces你好温油
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
typedef pair<int,int> point;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
char s[3][n+1];
for(int i=1; i<=2; i++)
{
cin>>s[i];
}
queue<point> q;
q.push((point){1,0});
int isChecked[3][n+1];
memset(isChecked,0,sizeof(isChecked));
isChecked[1][0]=1;
while(!q.empty())
{
point tmp=q.front();
int x=tmp.first,y=tmp.second;
//printf("%d %d\n",x,y);
isChecked[x][y]=1;
if(x==2&&y==n-1)
{
goto correct;
}
if(x+1<=2)
{
if(s[x+1][y]=='>'&&y+1<=n-1&&isChecked[x+1][y+1]==0)
{
q.push((point){x+1,y+1});
isChecked[x+1][y+1]=1;
}
else if(s[x+1][y]=='<'&&y-1>=0&&isChecked[x+1][y-1]==0)
{
q.push((point){x+1,y-1});
isChecked[x+1][y-1]=1;
}
}
if(y-1>=0)
{
if(y-2>=0&&s[x][y-1]=='<'&&isChecked[x][y-2]==0)
{
q.push((point){x,y-2});
isChecked[x][y-2]=1;
}
}
if(y+1<=n-1)
{
if(y+2<=n-1&&s[x][y+1]=='>'&&isChecked[x][y+2]==0)
{
q.push((point){x,y+2});
isChecked[x][y+2]=1;
}
}
if(x-1>=1)
{
if(s[x-1][y]=='>'&&y+1<=n-1&&isChecked[x-1][y+1]==0)
{
q.push((point){x-1,y+1});
isChecked[x-1][y+1]=1;
}
else if(s[x-1][y]=='<'&&y-1>=0&&isChecked[x-1][y-1]==0)
{
q.push((point){x-1,y-1});
isChecked[x-1][y-1]=1;
}
}
q.pop();
}
/*for(int i=1;i<=2;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d ",isChecked[i][j]);
}
printf("\n");
}*/
printf("NO\n");
continue;
correct:
printf("YES\n");
}
return 0;
}
2024_SCAU春季个人排位赛2(23级)
B.Elections(CF1043A)
已知一个人在各地区的得票数,问最小总票数使得他输掉选举
数据很小,遍历求解即可
#include <iostream>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
int m=0,a[n];
int E=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
m=max(m,a[i]);
E+=a[i];
}
int k;
for(k=m;1;k++)
{
int A=0;
for(int i=0;i<n;i++)
{
A+=(k-a[i]);
}
if(A>E)
break;
}
printf("%d\n",k);
return 0;
}
G.Simple Design(CF1884A)
给n和k,要求比n大的最小的y使得其各位数字加起来是k的倍数
虽然数据不是特别大,但是倒置高精度直接秒了,写一个数组+1的函数遍历就行
#include <iostream>
#include <string>
using namespace std;
void pl(char s[],int &n)
{
s[0]++;
for(int i=0;i<n;i++)
{
if(s[i]>'9')
{
if(i+1<n)
{
s[i+1]++;
}
else
{
s[i+1]='1';
n++;
}
s[i]-=10;
}
}
}
int all(char s[],int n)
{
int ret=0;
for(int i=0;i<n;i++)
{
ret+=s[i]-'0';
}
return ret;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
string s;
int x;
cin>>s;
cin>>x;
int n=s.length();
int c=0;
int a[n]={0};
for(int i=0;i<n;i++)
{
a[i]=s[i]-'0';
c+=a[i];
}
if(c%x==0)
{
cout<<s<<endl;
}
else
{
char brand[15]={0};
for(int i=n-1,j=0;i>=0;i--,j++)
{
brand[j]=s[i];
}
//printf("n=%d\n",n);
while(all(brand,n)%x!=0)
{
pl(brand,n);
}
//printf("n=%d\n",n);
for(int i=n-1;i>=0;i--)
printf("%c",brand[i]);
printf("\n");
}
}
return 0;
}
H.Array Rearrangement(CF1445A)
给数组a和b,问能不能重新排列b使得每个对应位置的a和b加起来都小于x
最大加最小遍历一层就完事儿了
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,k;
scanf("%d%d",&n,&k);
int a[n],b[n];
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);
for(int i=0; i<n; i++)
{
scanf("%d",&b[i]);
}
sort(b,b+n);
for(int i=0; i<n; i++)
{
int j=n-1-i;
if(a[i]+b[j]>k)
goto lose;
}
printf("Yes\n");
continue;
lose:
printf("No\n");
}
return 0;
}
2024_SCAU春季个人排位赛3(23级)
一个星期打两场太变态了 想原地退役了
A.Challenging Valleys(CF1760D)
给一个数组,问是不是只有一个极小值
数据小,套两层遍历结束了,签到题
#include <iostream>
#include <queue>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int a[n];
int m=1e9;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int cnt=0;
int tmp;
for(int i=0;i<n;i++)
{
if(a[i]<a[i-1]||i==0)
{
int j=i;
int flag=0;
while(a[j]==a[i])
{
j++;
if(j==n)
{
flag=1;
break;
}
}
if(a[i]<a[j]||flag==1)
{
cnt++;
//printf("i=%d j=%d\n",i,j);
}
}
}
if(cnt==1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
H.Paint the Numbers(CF1209A)
一个数组里一批数的gcd大于1就涂成一个颜色,问最小颜色数
也是两层循环,涂过的continue,没涂过的找gcd
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
int a[n],c[n]={0};
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);
int cnt=0;
for(int i=0;i<n;i++)
{
if(c[i]==0)
{
cnt++;
c[i]=1;
for(int j=i;j<n;j++)
{
if(a[j]%a[i]==0)
{
c[j]=1;
}
}
}
}
printf("%d\n",cnt);
return 0;
}
D.Wooden Sticks(POJ1065)
每个棍子有两个数值v和w,如果下一个处理的棍子v和w有一个值比上一个小机器就要花1分钟准备,问最少处理完所有棍子所需要的准备时间
贪心,狠狠地贪心
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
struct stick
{
int l;
int w;
};
bool stickcmp(stick x,stick y)
{
if(x.l==y.l)
return x.w<y.w;
return x.l<y.l;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
stick s[5010];
for(int i=0;i<n;i++)
{
scanf("%d%d",&s[i].l,&s[i].w);
}
int is[5010]={0};
sort(s,s+n,stickcmp);
int ans=0;
for(int i=0;i<n;i++)
{
if(is[i]==1)
continue;
is[i]=1;
//printf("当i=%d时,转化的j有",i);
ans++;
int ltmp=s[i].l;
int wtmp=s[i].w;
for(int j=i+1;j<n;j++)
{
if(is[j]==1)
continue;
//printf("%d ",j);
if(s[j].l>=ltmp&&s[j].w>=wtmp)
{
ltmp=s[j].l;
wtmp=s[j].w;
is[j]=1;
}
}
//printf("\n");
}
printf("%d\n",ans);
}
return 0;
}
Codeforces Round 935 (Div. 3)
冲击pupil失败的第一次,遗憾-20
A. Setting up Camp
a个人只能一个人住帐篷,b个人所在帐篷必须有3个人,c个人无所谓,问能不能完成任务,能的话帐篷最小多少个
C语言入门题,感觉不如...三角形能不能形成+求周长面积捏
#include <iostream>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
long long a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
long long cnt=a;
if((b/3+1)*3>(b+c)&&b%3!=0)
printf("-1\n");
else
{
if(b%3==0)
{
cnt+=b/3;
cnt+=c/3;
if(c%3!=0)
cnt++;
}
else if(b%3==1)
{
cnt+=b/3;
c+=1;
cnt+=c/3;
if(c%3!=0)
cnt++;
}
else if(b%3==2)
{
cnt+=b/3;
c+=2;
cnt+=c/3;
if(c%3!=0)
cnt++;
}
printf("%lld\n",cnt);
}
}
return 0;
}
B. Fireworks
两种烟花分别每a秒每b秒放一次,持续时间相等且已知,问最多同时看到多少烟花
guessforces,狠狠地猜!可以以第一次放烟花为基准,第一次持续时间内,看能多出多少个a和b,最后加上一开始那两个就行
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
unsigned long long a,b,m;
cin>>a>>b>>m;
unsigned long long cnt=m/a;
cnt+=m/b;
//if(a>=b)
// cnt+=m/(a-b+1);
//else
// cnt+=m/(b-a+1);
cnt+=2;
cout<<cnt<<endl;
}
return 0;
}
C. Left and Right Houses
数组为0表示想在左边,为1表示想在右边,找一个离中间最近的划线处,使得左右都有大于一半的人满足要求
维护left和right两个数组,分别表示划在i右边左边多少人满足和右边多少人满足,记得两次遍历方向相反,最后从中间开始遍历找就行
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
string s;
cin>>n;
cin>>s;
s=' '+s;
vector<int>left(n+3,0),right(n+3,0);
for(int i=1; i<=n; i++)
{
left[i]=left[i-1]+(s[i]=='0');
}
for(int i=n; i>=1; i--)
{
right[i]=right[i+1]+(s[i]=='1');
}
queue<int>ans;
for(int i=0; i<=n; i++)
{
if(left[i]>=(i+1)/2&&right[i+1]>=(n-i+1)/2)
{
ans.push(i);
}
}
if(ans.empty())
{
printf("0\n");
continue;
}
double ned=1.0*n/2;
int ret=n;
while(!ans.empty())
{
int now=ans.front();
if (fabs(1.0 * n / 2 - 1.0 * now) < ned)
{
ned = fabs(1.0 * n / 2 - 1.0 * now);
ret = now;
}
else if (fabs(1.0 * n / 2 - 1.0 * now) == ned)
{
ret = min(ret, now);
}
ans.pop();
}
printf("%d\n",ret);
}
return 0;
}
D. Seraphim the Owl
往前插队,想到第i个位置要给ai块钱加上路过的所有bj块钱,求到前m位花的最少得钱
贪心dp都行,我用的是贪心
#include <iostream>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
long long a[n+1],b[n+1];
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&b[i]);
}
long long pro[n+2]={0};
for(int i=1;i<=n;i++)
{
pro[i]=pro[i-1]+min(a[i],b[i]);
}
long long ans=1e17;
for(int i=1;i<=m;i++)
{
ans=min(ans,a[i]+pro[n]-pro[i]);
}
printf("%lld\n",ans);
}
return 0;
}
E.Binary Search
一个笨比对一个没排序的数组直接二分,要我帮他擦屁股,能找到万事大吉,找不到我要手动交换两个数
其实还是二分,然后再找一下正常的值,把位置交换一下就行
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,x;
scanf("%d%d",&n,&x);
vector<int> s(n+1);
for(int i=1;i<=n;i++)
{
scanf("%d",&s[i]);
}
int a=find(s.begin()+1,s.end(),x)-s.begin();
int l = 1, r = n + 1;
while(r-l!=1)
{
int mid=(l+r)/2;
if(s[mid]<=x)
{
l=mid;
}
else
r=mid;
}
if(s[l]==x)
printf("0\n");
else
printf("1\n%d %d\n",a,l);
}
return 0;
}
Codeforces Round 936 (Div. 2)
冲击pupil失败的第二次,遗憾-7
后面的真的一点不会,纯纯手速场,偏偏我A题忘了多case卡了半天
A. Median of an Array
可以做任意次数对任意数+1,要求最后中位数比原本的+1
从中位数的位置往后找,跟他一样的全部都要+1一次才能保证中位数+1,要不然一排序有回去了
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int a[n];
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
int mid=0;
if(n%2==0)
mid=n/2-1;
else
mid=n/2;
int cnt=0;
for(int i=mid;i<n;i++)
{
if(a[i]==a[mid])
cnt++;
}
printf("%d\n",cnt);
}
return 0;
}
B. Maximum Sum
给一个数组和执行步骤数,每一次你都可以取任意子串把这段子串的和插入其中任意位置,求最后能得出的最大数组合
前缀和然后疯狂乘2就行,记得小于0要特判,还有记得开long long
#include <iostream>
#include <cmath>
#define MOD 1000000007
long long MaxSubseqSum4(long long A[], long long N)
{
long long ThisSum, MaxSum;
long long i;
ThisSum = MaxSum = 0;
for (i = 0; i < N; i++)
{
ThisSum += A[i];
if (ThisSum>MaxSum)
MaxSum = ThisSum;
else if (ThisSum < 0)
ThisSum = 0;
}
return MaxSum;
}
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
long long n,k;
scanf("%lld%lld",&n,&k);
long long a[n],sum[n];
for(int i=0; i<n; i++)
{
scanf("%lld",&a[i]);
if(i==0)
sum[i]=a[i];
else
sum[i]=a[i]+sum[i-1];
}
long long m=MaxSubseqSum4(a,n);
/*for(int i=0; i<n; i++)
{
m=max(sum[i],m);
for(int j=i; j<n; j++)
{
if(i==0)
continue;
m=max(sum[j]-sum[i-1],m);
}
}*/
long long tmp=m;
for(int i=1; i<=k; i++)
{
m*=2;
m%=MOD;
}
long long cnt=(sum[n-1]%MOD+m-tmp)%MOD;
if(cnt<0)
cnt=MOD+cnt;
//printf("sum=%d m=%d\n",sum[n-1],m);
printf("%lld\n",cnt);
}
return 0;
}
2024_SCAU春季个人排位赛5(23级)
没打第4场因为去做义务劳动了 在街上扫了一下午树叶
C.Bright, Nice, Brilliant(CF1734B)
题意太复杂丢给AI吧
可以直接guess,但是还是推一下给你们康康哈
为了使数字最大那我第一行一定要放灯泡,然后为了每行相等所以中间不能放灯泡,闭着眼睛输出n行,每行n个数,只有第一个和最后一个是1,别的都是0就行,代码难度还不如生成菱形(
顺带一提,笨比数字之间忘加空格wa了一发喵
#include <iostream>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
if(j==1||j==i)
printf("1 ");
else
printf("0 ");
}
printf("\n");
}
}
return 0;
}
H.Destroyer(CF1836A)
机器人站成若干队,每个机器人输出他前面机器人的个数,问你有没有可能成立
因为每队最多100人,那开个桶,然后遍历比较就行,要求是后面的数必须比前面的小
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int b[150]={0};
for(int i=0;i<n;i++)
{
int c;
scanf("%d",&c);
b[c]++;
}
int flag=1;
for(int i=1;i<=100;i++)
{
if(b[i]>b[i-1])
{
flag=0;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
I.Spelling Check(CF39J)
给两个字符串,上面字符串删掉一个字符能不能变成下面的,能的话有多少种删法,分别是删掉第几个位置的字符
哥们儿是真的不明白这题洛谷怎么能标到蓝的,太水了,数据也小,前后一遍历就结束了,好像有笨比用的字符串哈希,也能过
#include <iostream>
using namespace std;
int main()
{
string s1;
string s2;
cin>>s1;
cin>>s2;
s1=' '+s1;
s2=' '+s2;
int l1=s1.length()-1;
int l2=s2.length()-1;
if(l1-l2!=1)
{
printf("0\n");
return 0;
}
int l=1,r=l1;
for(l=1; s1[l]==s2[l]; l++);
for(r=l1; s2[r-1]==s1[r]; r--);
if(r>l)
printf("0\n");
else
{
printf("%d\n",l-r+1);
for(int k=r; k<=l; k++)
{
printf("%d ",k);
}
printf("\n");
}
return 0;
}
A.Memory(QOJ7747)
递推公式推出来了但是一直wa 当时我真的以为我要拿一血了(
直接递推wa的版本
#include <iostream>
#define MOD 1e9
using namespace std;
int main()
{
int n;
scanf("%d",&n);
double a[n];
for(int i=0;i<n;i++)
{
scanf("%lf",&a[i]);
}
double now=a[0];
for(int i=0;i<n;i++)
{
if(i==0)
now=a[0];
else
now=now/2+a[i];
if(now>0)
printf("+");
else if(now<0)
printf("-");
else
printf("0");
}
return 0;
}
其实这个时候已经意识到数据范围的问题了,但只是加了个MOD还没来得及用就结束了,后来补题细想了一下把整数和小数部分分开 小数部分也不是必须要用一个double维护,太麻烦了,只要整数部分可以被2整除,那么下一次的小数部分的正负就和上次一样,否则就重置一下就行
#include <iostream>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
long long a[n];
for(int i=0;i<n;i++)
scanf("%lld",&a[i]);
int little=0;
long long sum=0;
for(int i=0;i<n;i++)
{
sum+=a[i];
if(sum>0)
printf("+");
else if(sum<0)
printf("-");
else
{
if(little==1)
printf("+");
else if(little==-1)
printf("-");
else
printf("0");
}
if(sum%2!=0)
{
if(sum>0)
little=1;
else
little=-1;
}
sum/=2;
}
return 0;
}
而且赛时没想起来,突然发现这种数据范围出问题直接换Python秒不就行了,错失一血捏
n=int(input())
a=input().split()
su=int(a[0])
ans=""
if su>0:
ans+="+"
elif su==0:
ans+="0"
else:
ans+="-"
l=0
for i in range(1,n):
l+=1
su+=int(a[i])<<l
if su>0:
ans+="+"
elif su==0:
ans+="0"
else:
ans+="-"
print(ans)
D.Mike and gcd problem(CF798C)
对数组中任意连续两个数a和b都可以使得他们变成a-b和a+b,使得整个数组有大于1的gcd的最小操作数
如果原来的数组就有合适gcd当然最好 没有的话统一变成偶数就行 然后就是贪心 两个奇数在一起可以一次全变偶数 一奇一偶就需要两次操作
特别注意特判 不要上来就全变偶数(赛时我就这么寄的捏)
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
int s[n],m=0;
for(int i=0; i<n; i++)
{
scanf("%d",&s[i]);
if(i==0)
m=s[i];
else
m=__gcd(m,s[i]);
}
if(m>1)
printf("YES\n0\n");
else
{
int cnt=0;
for(int i=0; i<n-1; i++)
{
if(s[i]%2!=0&&s[i+1]%2!=0)
{
long long a=s[i],b=s[i+1];
s[i]=a-b;
s[i+1]=a+b;
cnt++;
}
}
for(int i=0; i<n; i++)
{
if(s[i]%2!=0)
{
long long a=s[i],b=s[i+1];
s[i]=a-b;
s[i+1]=a+b;
cnt++;
a=s[i],b=s[i+1];
s[i]=a-b;
s[i+1]=a+b;
cnt++;
}
}
printf("YES\n%d\n",cnt);
}
return 0;
}
Codeforces Round 853 (Div. 2)
队内vp 最近补不动题 只丢赛时写出来的
A. Serval and Mocha's Array
问能否排列数组使得前2到n项构成的所有子串都满足其gcd小于长度
其实只需要对最开头的部分做特殊判断就行,有1就都好办,没1凑1,其他情况遍历
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int a[n];
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int flag=0;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(__gcd(a[i],a[j])<=2)
{
flag=1;
break;
}
}
if(flag==1)
break;
}
if(flag==0)
printf("No\n");
else
{
printf("Yes\n");
}
}
return 0;
}
B. Serval and Inversion Magic
先遍历预处理,对左右不同的做标记,最后只能反转一次,所以要把这些全覆盖且原本左右相等的要同时覆盖,再遍历看分了多少段按cnt判断即可
#include <iostream>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
string s;
cin>>s;
int mid=n/2;
int sign[mid]={0};
int cnt=0;
for(int i=0;i<mid;i++)
{
int j=n-1-i;
if(s[i]==s[j])
sign[i]=1;
else
sign[i]=0;
if(sign[i]!=sign[i-1]&&i!=0)
cnt++;
}
//printf("cnt=%d\n",cnt);
if(sign[0]==1)
{
if(cnt<3)
printf("Yes\n");
else
printf("No\n");
}
else
{
if(cnt<2)
printf("Yes\n");
else
printf("No\n");
}
}
return 0;
}
Codeforces Round 937 (Div. 4)
我最爱的Div4,赶在三月份的尾巴成功pupil,好耶!
A. Stair, Peak, or Neither?
初学if的练习题 不解释
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(c>b&&b>a)
printf("STAIR\n");
else if(b>c&&b>a)
printf("PEAK\n");
else
printf("NONE\n");
}
return 0;
}
B. Upscaling
输入n,按图中规律输出对应的字符串
感觉不如...打印空心菱形...
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
if(i%2!=0)
{
for(int j=1;j<=n;j++)
{
if(j%2!=0)
printf("##");
else
printf("..");
}
printf("\n");
for(int j=1;j<=n;j++)
{
if(j%2!=0)
printf("##");
else
printf("..");
}
printf("\n");
}
else
{
for(int j=1;j<=n;j++)
{
if(j%2==0)
printf("##");
else
printf("..");
}
printf("\n");
for(int j=1;j<=n;j++)
{
if(j%2==0)
printf("##");
else
printf("..");
}
printf("\n");
}
}
}
return 0;
}
C. Clock Conversion
24小时制转成12小时制 记得0点和12点都要特判
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int a,b;
scanf("%d:%d",&a,&b);
int flag=0;
if(a>=12)
flag=1;
if(a>12)
a-=12;
if(a==0)
a+=12;
printf("%02d:%02d ",a,b);
if(flag==1)
printf("PM\n");
else
printf("AM\n");
}
return 0;
}
D. Product of Binary Decimals
先打表,就32个数,再拿递归就行
#include <bits/stdc++.h>
using namespace std;
int have[31]={10, 11, 100, 101, 110, 111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111, 10000, 10001, 10010, 10011, 10100, 10101, 10110, 10111, 11000, 11001, 11010, 11011, 11100, 11101, 11110, 11111, 100000};
int check(int n)
{
if(n==1)
return 1;
//printf("我进来啦!\n");
for(int i=0;i<31;i++)
{
if(n==have[i])
return 1;
}
for(int i=0;i<31;i++)
{
if(n%have[i]==0)
{
if(check(n/have[i]))
return 1;
}
}
return 0;
}
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
if(check(n))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
Codeforces Round 787 (Div. 3)
A. Food for Animals
顺序结构入门题 签个到先
#include <iostream>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int a,b,c,x,y;
scanf("%d%d%d%d%d",&a,&b,&c,&x,&y);
x-=a;
y-=b;
if(x<0)
x=0;
if(y<0)
y=0;
if(c>=x+y)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
B. Make It Increasing
对每个数都可以进行整除2操作 问有没有机会把原数组变成严格递增序列
从后往前遍历就行 注意出现0的话要多加一个判断
#include <iostream>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int a[n]={0};
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int cnt=0;
for(int i=n-1;i>0;i--)
{
while(a[i]<=a[i-1])
{
a[i-1]/=2;
cnt++;
if(a[i-1]==0)
{
if(a[i]==0)
goto bad;
else
continue;
}
}
}
printf("%d\n",cnt);
continue;
bad:
printf("-1\n");
}
return 0;
}
C. Detective Task
抓小偷 每个人都进去过 有人说自己看到了画 有人说没看到 有人说不记得 问小偷的可能性
就找01交替处 遇到?就把个数加上去
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
string s;
cin>>s;
int l=s.length();
if(s[0]=='0')
printf("1\n");
else
{
int ans=0;
for(int i=0;i<l;i++)
{
if(s[i]!='?')
{
if(s[i]=='1')
ans=1;
else
{
printf("%d\n",ans+1);
goto nxt;
}
}
else
ans++;
}
printf("%d\n",ans);
}
nxt:
continue;
}
return 0;
}
E. Replace With the Previous, Minimize
每次可以选定一个字母 把字符串里所有这个字母减一 问给定操作次数能改出的字典序最小的串
本来直接贪的 后来发现不行 可以先操作后面大的然后让字典序更小 所以要先找能剪到a的最大的字符 然后全拿下就行
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int n,k;
scanf("%d%d",&n,&k);
string s;
cin>>s;
char c='a';
for(int i=0; i<n; i++)
{
if(s[i]>c)
{
if(s[i]-'a'>k)
{
k-=c-97;
int minn=s[i]-k;
for(char h=s[i]; h>minn; h--)
for(int j=0; j<n; j++)if(s[j]==h)s[j]=h-1;
break;
}
else if(c<s[i])
c=s[i];
}
}
for(int i=0;i<n;i++)
if(s[i]<=c)
s[i]='a';
cout<<s<<endl;
}
return 0;
}
2024_SCAU春季个人排位赛6(23级)
迟到40分钟 但是手感超好 上场20分钟秒了三题 大杀特杀
D.Ichihime and Triangle(CF1337A)
给四个数 要求在其形成的三个区间内各找一个数形成一个三角形
前两个取最大 最后一个取最小就行
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
long long a,b,c,d;
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
printf("%lld %lld %lld\n",b,c,c);
}
return 0;
}
B.What is for dinner?(CF33A)
这题主要难度在英语 大段大段的文字看的头疼 偏偏题目本身又简单的不行
为了给各位原汁原味的体验 特把英文题面丢进来
看懂题然后你就能秒了
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
int c[1010]={0};
for(int i=0;i<1010;i++)
{
c[i]=1e9;
}
while(n--)
{
int r,now;
scanf("%d%d",&r,&now);
c[r]=min(c[r],now);
}
int all=0;
for(int i=1;i<=m;i++)
{
if(c[i]==1e9)
all+=0;
else
all+=c[i];
}
if(all>=k)
printf("%d\n",k);
else
printf("%d\n",all);
return 0;
}
J.Vova and Train(CF1066A)
k的整数倍的位置都有一个点 再给一个区间 把区间内所有点抹掉 问你还剩多少个
按左边的余数补数字 记得0要特判 然后减掉就行
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
int L,v,l,r;
scanf("%d%d%d%d",&L,&v,&l,&r);
int cnt=L/v;
int length=r-l+1;
if(l%v==0)
{
length+=v-1;
}
else
{
length+=l%v-1;
}
cnt-=(length/v);
printf("%d\n",cnt);
}
return 0;
}
E.Exam in MAC(CF1935D)
惊了 这场比赛我当时还打了(详见上期博客) 不过当时不会写这次写出来了
给定一个范围 给一堆s 对每个s要排除范围内加起来和减出来等于s的数对 问还剩多少数对
遍历肯定不行 反过来思考 一共有多少数对 减去加起来等于s的 减去减出来等于s的
我本来只写了这两个 后来发现答案普遍偏小 说明会有重复
要把加起来减起来为不同s的数对个数减掉
a+b=x a-b=y 得出x和y奇偶性相同 那就是所有s里面奇数数对和加偶数数对和的个数
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
long long n,c;
scanf("%lld%lld",&n,&c);
long long cnt=(c+2)*(c+1)/2;
long long ou=0,ji=0;
while(n--)
{
long long s;
scanf("%lld",&s);
if(s%2==0)
ou++;
else
ji++;
cnt-=s/2+1;
cnt-=c-s+1;
}
cnt+=(ou+1)*ou/2+(ji+1)*ji/2;
printf("%lld\n",cnt);
}
return 0;
}