A. Do Not Be Distracted!
题意
给定一个字符串,每种字母表示一种任务,请问任务是否连续完成,没有分开
思路
- 暴力统计,一旦任务断开就标记,再出现就结束
时间复杂度
O(T*n)
参考代码
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#define max(a,b) (a>b?a:b)
using namespace std;
int t,n,cnt[500];
string s;
int main(){
scanf("%d",&t);
while(t--){
memset(cnt,0,sizeof(cnt));
scanf("%d",&n);
cin>>s;
int ans=0;
for(int i=1;i<n;i++){
if(s[i]!=s[i-1]){
if(cnt[s[i-1]]!=0)
ans=1;
cnt[s[i-1]]++;
}
}
if(cnt[s[n-1]]!=0)
ans=1;
printf("%s\n",ans?"NO":"YES");
}
}
B. Ordinary Numbers
题意
对于n,请问[1,n]中有多少个所有数码都一样的数字(如2,55,888)
思路
- 暴力统计,将所有数字预处理,直接统计即可
时间复杂度
O(T*大常数)
参考代码
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
int t,n;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int ans=0;
if(n>=1) ans++;
if(n>=2) ans++;
if(n>=3) ans++;
if(n>=4) ans++;
if(n>=5) ans++;
if(n>=6) ans++;
if(n>=7) ans++;
if(n>=8) ans++;
if(n>=9) ans++;
if(n>=11) ans++;
if(n>=22) ans++;
if(n>=33) ans++;
if(n>=44) ans++;
if(n>=55) ans++;
if(n>=66) ans++;
if(n>=77) ans++;
if(n>=88) ans++;
if(n>=99) ans++;
if(n>=111) ans++;
if(n>=222) ans++;
if(n>=333) ans++;
if(n>=444) ans++;
if(n>=555) ans++;
if(n>=666) ans++;
if(n>=777) ans++;
if(n>=888) ans++;
if(n>=999) ans++;
if(n>=1111) ans++;
if(n>=2222) ans++;
if(n>=3333) ans++;
if(n>=4444) ans++;
if(n>=5555) ans++;
if(n>=6666) ans++;
if(n>=7777) ans++;
if(n>=8888) ans++;
if(n>=9999) ans++;
if(n>=11111) ans++;
if(n>=22222) ans++;
if(n>=33333) ans++;
if(n>=44444) ans++;
if(n>=55555) ans++;
if(n>=66666) ans++;
if(n>=77777) ans++;
if(n>=88888) ans++;
if(n>=99999) ans++;
if(n>=111111) ans++;
if(n>=222222) ans++;
if(n>=333333) ans++;
if(n>=444444) ans++;
if(n>=555555) ans++;
if(n>=666666) ans++;
if(n>=777777) ans++;
if(n>=888888) ans++;
if(n>=999999) ans++;
if(n>=1111111) ans++;
if(n>=2222222) ans++;
if(n>=3333333) ans++;
if(n>=4444444) ans++;
if(n>=5555555) ans++;
if(n>=6666666) ans++;
if(n>=7777777) ans++;
if(n>=8888888) ans++;
if(n>=9999999) ans++;
if(n>=11111111) ans++;
if(n>=22222222) ans++;
if(n>=33333333) ans++;
if(n>=44444444) ans++;
if(n>=55555555) ans++;
if(n>=66666666) ans++;
if(n>=77777777) ans++;
if(n>=88888888) ans++;
if(n>=99999999) ans++;
if(n>=111111111) ans++;
if(n>=222222222) ans++;
if(n>=333333333) ans++;
if(n>=444444444) ans++;
if(n>=555555555) ans++;
if(n>=666666666) ans++;
if(n>=777777777) ans++;
if(n>=888888888) ans++;
if(n>=999999999) ans++;
printf("%d\n",ans);
}
}
C. Not Adjacent Matrix
题意
对于n,请将1到n*n的数字填到n*n的矩阵当中,使得相邻位置的元素都不相邻,无解输出-1
思路
- n=1,直接输出即可
- n=2,无解
- 将格子分奇偶,行列之和奇数的从上到下先填,剩下的后填,就可以满足题目要求
时间复杂度
参考代码
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#define max(a,b) (a>b?a:b)
using namespace std;
int t,n,ans[110][110];
string s;
int main(){
scanf("%d",&t);
while(t--){
memset(ans,0,sizeof(ans));
scanf("%d",&n);
if(n==1){
printf("1\n");
continue;
}
if(n==2){
printf("-1\n");
continue;
}
int cnt=0;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if((i+j)&1) ans[i][j]=++cnt;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(ans[i][j]==0) ans[i][j]=++cnt;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
printf("%d ",ans[i][j]);
printf("\n");
}
}
}
D. Same Differences
题意
对于数组A,请问多少对数满足
思路
- 首先进行移项,原式即为
- 不难发现,式子具有传递性,用map统计集合即可得到集合大小
时间复杂度
参考代码
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
int t,n;
int main(){
scanf("%d",&t);
while(t--){
map<int,int> mp;
scanf("%d",&n);
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
mp[x-i]++;
}
long long ans=0;
map<int,int>::iterator iter;
iter = mp.begin();
while(iter != mp.end()){
long long cnt=iter->second;
ans+=(cnt*(cnt-1))/2;
iter++;
}
printf("%lld\n",ans);
}
}
E. Arranging The Sheep
题意
有一群羊在一条线上,每次可以让一头左移或者右移一个单位,最少多少次能够把羊聚在一起(必须全部连续)
思路
- 首先假设最优位置是pos,则我们需要:将左边的羊聚过来,将右边的羊聚过来
- 首先可以做前缀和,后缀和,搞清前后一共有多少羊
- 计算左边/右边羊聚过来的代价,如果这里有羊,不用管它,否则增加一下代价
- 尝试枚举每个位置,注意:如果这里没有羊,可以让左边或者右边的退一步
时间复杂度
O(T*n)
参考代码
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#define max(a,b) (a>b?a:b)
using namespace std;
const int maxn=1e6+10;
int t,n,pre[maxn],after[maxn];
long long prea[maxn],aa[maxn];
string s;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
cin>>s;
s=" "+s;
for(int i=1;i<=n;i++) pre[i]=pre[i-1]+(s[i]=='*');
after[n+1]=0;
for(int i=n;i>=1;i--) after[i]=after[i+1]+(s[i]=='*');
for(int i=1;i<=n;i++)
if(s[i]=='*')
prea[i]=prea[i-1];
else
prea[i]=prea[i-1]+pre[i-1];
aa[n+1]=0;
for(int i=n;i>=1;i--)
if(s[i]=='*')
aa[i]=aa[i+1];
else
aa[i]=aa[i+1]+after[i+1];
long long ans=1;
ans<<=60;
for(int i=1;i<=n;i++){
long long poss=0;
if(s[i]=='*') ans=min(ans,prea[i]+aa[i]);
else ans=min(ans,prea[i]+aa[i]-max(pre[i],after[i]));
}
printf("%lld\n",ans);
}
}
F1. Guess the K-th Zero (Easy version)
题意
长度为n的数组,元素为0或1,有20次询问区间和的机会,求第k个0在那个位置
思路
- 每次询问1-x的前缀和,二分即可得到答案
询问次数
参考代码
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
int t,n,k;
int main(){
scanf("%d%d%d",&n,&t,&k);
int cnt=20,l=1,r=n;
while(cnt--){
if(l>r) break;
int mid=(l+r)>>1;
printf("? %d %d\n",1,mid);
fflush(stdout);
int x;
scanf("%d",&x);
if(x+k<=mid){
r=mid-1;
}else{
l=mid+1;
}
}
printf("! %d",r+1);
fflush(stdout);
}