A. Do Not Be Distracted!
读了十分钟才看懂题意我菜死了QAQ
查询是否出现相同字母的连续区间即可
string s;
map<char,int>mp;
void solves(){
int n;cin>>n;
cin>>s;
mp.clear();
for(int i=0;i<n;++i){
if(!mp[s[i]]){
mp[s[i]]=1;
int j=i;
while(s[i]==s[j]) ++j;
if(j==n)break;
i=j-1;
} else{
cout<<"NO\n";return ;
}
}
cout<<"YES\n";
}
B. Ordinary Numbers
位 数 1 1 2 3 . . . 8 9 2 11 22 33 . . . 88 99 3 111 222 333 . . . 888 999 . . . . . . . . . . . . . . . . . . . . . 8 11111111 22222222 33333333 . . . 88888888 99999999 9 111111111 222222222 333333333 . . . 888888888 999999999 \begin{array}{c|ccc} 位数 & \text{} & \text{} & \text{} \\ \hline 1 & 1 & 2 & 3 & ... & 8 & 9\\ 2 & 11 & 22 & 33 & ... & 88 & 99\\ 3 & 111 & 222 & 333 & ... & 888 & 999\\ ... & ... & ... & ...&...&...&...\\ 8 & 11111111 & 22222222 & 33333333 &...&88888888&99999999\\ 9 & 111111111 & 222222222 & 333333333 &...&888888888&999999999\\ \end{array} 位数123...89111111...11111111111111111222222...22222222222222222333333...33333333333333333..................888888...88888888888888888999999...99999999999999999
显然十进制n位数必有(n-1)*9个ordinary numbers,然后再与其同位数的111…,222…,…,999…比较。
void solves(){
ll n;cin>>n;
int cnt=0;
int m=n;
while(n){
++cnt;
n/=10;
}
int ans=(cnt-1)*9;
ll re=1;
for(int i=1;i<cnt;++i) re=re*10+1;
for(ll i=1;i<=10;++i){
if(re*i>m){
ans+=(i-1);
break;
}
}
cout<<ans<<endl;
}
C. Not Adjacent Matrix
沿着间隔的对角线填充必能使各数不相邻。但n=2时必有任一对角线都互相相邻。
说的有点抽象,举个栗子:
先从左下角依次沿间隔的对角线填充到右上角
5
10
13
6
11
2
7
12
3
8
1
4
9
\begin{array}{c|c|c|c|c} 5 & &10 & &13 \\ \hline & 6 & & 11 &\\ \hline 2 & & 7 & &12 \\ \hline & 3& & 8 &\\ \hline 1 & &4& &9\\ \end{array}
52163107411813129
再倒回左下角第二条对角线按顺序沿间隔的对角线填充到右上角
5
20
10
24
13
16
6
21
11
25
2
17
7
22
12
14
3
18
8
23
1
15
4
19
9
\begin{array}{c|c|c|c|c} 5 & 20 &10 &24 &13 \\ \hline 16 & 6 & 21 & 11 &25\\ \hline 2 &17 & 7 & 22&12 \\ \hline 14& 3& 18 & 8 &23\\ \hline 1 & 15 &4& 19&9\\ \end{array}
51621412061731510217184241122819132512239
void dfs(int x,int y){
if(x==n+1||y==n+1)return ;
mp[x][y]=++tot;
return dfs(x+1,y+1);
}
void solves(){
cin>>n;
tot=0;
if(n==2){
cout<<-1<<endl;return ;
}
for(int i=n;i>0;i-=2) dfs(i,1);
for(int i=3;i<=n;i+=2) dfs(1,i);
for(int i=n-1;i>0;i-=2) dfs(i,1);
for(int i=2;i<=n;i+=2) dfs(1,i);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j)cout<<mp[i][j]<<" ";cout<<endl;
}
}
D. Same Differences
我真的好傻,最后半小时才想到正解,而且貌似还因为爆int wa了一次QAQ
要使得
a
j
−
a
i
=
j
−
i
a_j-a_i=j-i
aj−ai=j−i,则有
a
j
−
j
=
a
i
−
i
a_j-j=a_i-i
aj−j=ai−i。剩下的就是初中数学知识了。
const int N=2e5+7;
int a[N];
map<ll,ll>cnt;
void solves(){
int n;cin>>n;
cnt.clear();
ll ans=0;
for(ll i=1;i<=n;++i){
cin>>a[i];
++cnt[a[i]-i];
}
for(ll i=-n;i<=n;++i){
ans+=(cnt[i]-1)*cnt[i]/2;//这一步可能爆int(?)
}
cout<<ans<<endl;
}
E. Arranging The Sheep
这个题的思想和很久很久之前的一场div2的b题(为了找这个b题我翻了好久QAQ)是一样的,向中位数靠拢即可。只不过一个是二维的曼哈顿距离,一个是一维的。有点可惜,昨晚没时间读这题了QAQ。
ps有人问我怎么证明中位数,看到隔壁一个博主证挺好的,我就不证了。
string s;
void solves(){
int n;cin>>n>>s;
vector<int>sum;
int cnt=0;
for(int i=0;i<n;++i){
if(s[i]=='*'){
++cnt;
sum.push_back(i);
}
}
int mid=0;
if(sum.size()) mid=sum[cnt/2];
ll ans=0;
for(int i=0;i<sum.size();++i){
ans+=abs(sum[i]-( mid-(cnt/2-i) ));
}
cout<<ans<<endl;
}
F1. Guess the K-th Zero (Easy version)
一眼二分。n在2e5范围且只能查询20次,那就需要logn的解法,二分的复杂度也是刚好符合的。
void ask(int l,int r,int k){
if(l==r){
cout<<"! "<<l<<endl;
} else{
int m=(l+r)>>1;
cout<<"? "<<l<<" "<<m<<endl;
int val;cin>>val;
if(m-l+1-val<k){
ask(m+1,r,k+val-m+l-1);
} else{
ask(l,m,k);
}
}
}
void solves(){
int n,t,k;cin>>n>>t>>k;
ask(1,n,k);
}
F2. Guess the K-th Zero (Hard version)
看心情填坑
G. To Go Or Not To Go?
听说是sb题,但我感觉我是sb。
要么只传送一次,要么不传送。像样例那样中间截断的话跑两次bfs就好了。取两种情况的最小值就行了。还是要注意一下细节吧,我细节处理的不好wa了好几次。
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
const int N=2e3+7;
const int mod=1e9+7;
using namespace std;
ll mp[N][N],a[N][N],b[N][N];
int dir[4][2]{{1,0},{-1,0},{0,1},{0,-1}};
ll n,m,w;
ll INF=(1ll<<60);//初始化inf尽可能大一点
void bfs(int x,int y,ll cost[][N]){
queue<pair<int,int>>q;
pair<int,int>step;
q.push({x,y});
int nx,ny;
while(q.size()){
step=q.front();
q.pop();
for(int i=0;i<4;++i){
nx=step.first+dir[i][1];
ny=step.second+dir[i][0];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mp[nx][ny]!=-1&&cost[nx][ny]==-1){
cost[nx][ny]=cost[step.first][step.second]+1;
q.push({nx,ny});
}
}
}
}
void solves(){
cin>>n>>m>>w;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j)cin>>mp[i][j];
}
memset(a,-1,sizeof(a));
memset(b,-1,sizeof(b));
a[1][1]=b[n][m]=0;
bfs(1,1,a);
bfs(n,m,b);
ll ans1=INF,ans2=INF,ans=INF;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(mp[i][j]>0&&a[i][j]>=0){
ans1=min(ans1,a[i][j]*w+mp[i][j]);
}
}
}
for(int i=n;i>0;--i){
for(int j=n;j>0;--j){
if(mp[i][j]>0&&b[i][j]>=0){
ans2=min(ans2,b[i][j]*w+mp[i][j]);
}
}
}
if(a[n][m]==b[1][1]&&b[1][1]>0){
ans=min(a[n][m]*w,ans2+ans1);
} else{
ans=ans2+ans1;
}
cout<<(ans>=INF ? -1:ans)<<endl;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int OwO=1;
// cin>>OwO;
while(OwO--){
solves();
}
}