题解:给一段区间求连续出现的小写字母有多少个,
用前缀和记录前面有多少个连续出现的字母,记录作差即答案(给出左右边界求数量可以想前缀和)
#include<bits/stdc++.h>
using namespace std;
#define int long long
int sum[300005];
signed main(){
int n,q;
cin>>n>>q;
string s;
cin>>s;
for(int i=1;i<n;i++){
if(s[i]==s[i-1]){
sum[i]=sum[i-1]+1;
}
else sum[i]=sum[i-1];
}
for(int i=0;i<q;i++){
int l,r;
cin>>l>>r;
r--;
l--;
int ans=sum[r]-sum[l];
cout<<ans<<endl;
}
return 0;
}
模拟!!一生的痛!!,能模n小时。。。。。先全部将矩阵赋值成‘#’,然后一个一个扣赋值成'.'数据要是再大点就T。^-^;
#include<bits/stdc++.h>
using namespace std;
char ans[1000][1000];
signed main(){
int n;
cin>>n;
if(n==0)cout<<"#";
else {
int m=pow(3,n);
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
ans[i][j]='#';
}
}
for(int i=1;i<=n;i++){
int h=pow(3,i-1);
int endj=h+h;
int u=pow(3,i);
for(int o=0;o<m/u;o++){
for(int j=h+1+u*o;j<=endj+u*o;j++){
for(int r=0;r<m/u;r++){
for(int k=h+1+u*r;k<=endj+u*r;k++){
ans[j][k]='.';
}
}
}
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
cout<<ans[i][j];
}
cout<<endl;
}
}
return 0;
}
c-谜之二分,谜之条件,谜之check,
二分最小行宽度,check函数:
累加每一行的单词以及空格长度,不过这里的空格计数要小心,会卡你;
如果每一行的长度如果<=规定的最大行数,就说明行宽度还可以小一点;
就将右边界向左移动;
反之,左边界向右移动;
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[200005];
int n,m,l=1,r,ans;
bool check(int x){
int hang=0;
int sum=0;
for(int i=1;i<=n;i++){
if(sum==0){
sum=0;
hang++;
}
sum+=a[i];
if(sum<x)sum++;
if(sum==x)sum=0;
if(sum>x){
sum=a[i]+1;
hang++;
}
}
if(hang<=m)return 1;
else return 0;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
l=max(l,a[i]);
r+=a[i];
}
r+=n;
while(l<r){
int mid=(l+r)/2;
if(check(mid)==0){
l=mid+1;
}
else {
r=mid;
}
}
cout<<r<<endl;
}