读了十分钟才看懂题意我菜死了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";
}
位 数 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;
}
沿着间隔的对角线填充必能使各数不相邻。但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;
}
}
我真的好傻,最后半小时才想到正解,而且貌似还因为爆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;
}
这个题的思想和很久很久之前的一场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;
}
(看心情填坑OvO)