求a+b=n,且0
思路:
如果是偶数就有n/2-1,奇数就有n/2
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
int main(){
int T;
cin>>T;
while(T--){
long long n;
cin>>n;
if(n<=2) cout<<"0\n";
else {
if(n%2)
cout<<n/2<<endl;
else cout<<n/2-1<<endl;
}
}
return 0;
}
构造一个长度为n的字符串,使得每一个长度为a的子串都包含b个不同的字母。 1 ≤ a ≤ n ≤ 2000 , 1 ≤ b ≤ m i n ( 26 , a ) 1≤a≤n≤2000,1≤b≤min(26,a) 1≤a≤n≤2000,1≤b≤min(26,a)
构造一个长度为b的循环串就可以了
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
int main(){
int T;
cin>>T;
while(T--){
int n,a,b;
cin>>n>>a>>b;
char c=0;
for(int i=1;i<=n;++i){
cout<<char(c+'a');
c++;
c%=b;
}
cout<<endl;
}
return 0;
}
求将一个包含n个数的集合划分成两类,一类中的数都互不相同,二类中的数都相同,一二类的数字个数相同,求数字个数的最大值。
枚举集合二的数字情况,求最大值。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
set<int> S;
map<int,int> mmp;
int main(){
int T;
cin>>T;
while(T--){
int n;
scanf("%d",&n);
mmp.clear();
S.clear();
for(int i=1,x;i<=n;++i){
scanf("%d",&x);
mmp[x]++;
S.insert(x);
}
int ans=0;
for(auto it:S){
ans=max(ans,min((int)S.size()-1,mmp[it]));
ans=max(ans,min((int)S.size(),mmp[it]-1));
}
cout<<ans<<endl;
}
return 0;
}
将一个合法的数独矩阵,操作最多九次,使得每一行每一列每个一3×3的格子都包含至少两个相同的数字。
枚举每一行,不同行改变属于不同列和不同3×3的方格的小格子就可以了
#include
using namespace std;
const int N=100,M=9;
int a[N][N];
int main(){
int T;
scanf("%d",&T);
while(T--){
for(int i=1;i<=M;++i){
for(int j=1;j<=M;++j){
scanf("%1d",&a[i][j]);
}
}
a[1][1]=a[1][2];a[2][4]=a[2][5];a[3][7]=a[3][8];
a[4][2]=a[4][3];a[5][5]=a[5][6];a[6][8]=a[6][9];
a[7][3]=a[7][4];a[8][6]=a[8][7];a[9][9]=a[9][1];
for(int i=1;i<=M;++i){
for(int j=1;j<=M;++j){
printf("%d",a[i][j]);
}puts("");
}
}
return 0;
}
给出一个字符串构造出一个子序列,使得是一个ABA(A和B可以一样)型的回文串。 a i < = 26 , n < = 2000 a_i<=26,n<=2000 ai<=26,n<=2000
一上来就想的E2没思路,然后先过E1。先求每种数字的前缀和,枚举ABA之间的分割点。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=2010;
int a[N],f[N][30];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
memset(f,0,sizeof f);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;++i){
f[i][a[i]]++;
for(int j=1;j<=26;++j){
f[i][j]+=f[i-1][j];
}
}
int ans=0;
for(int j=1;j<=26;++j){
ans=max(ans,f[n][j]);
}
for(int i=1;i<=n;++i){
for(int j=i;j<=n;++j){
int ll=0,mid=0,rr=0,mid2=0;
for(int k=1;k<=26;++k){
ll=f[i-1][k];
rr=f[n][k]-f[j][k];
mid2=max(mid2,min(ll,rr));
}
for(int k=1;k<=26;++k){
mid=max(mid,f[j][k]-f[i-1][k]);
}
ans=max(ans,mid2*2+mid);
}
}
cout<<ans<<endl;
}
return 0;
}
给出一个字符串构造出一个子序列,使得是一个ABA(A和B可以一样)型的回文串。 a i < = 200 , n < = 200000 a_i<=200,n<=200000 ai<=200,n<=200000
看着复杂度还以为是DP,想了半个小时其实还是虾搞。先求每种数字的前缀和,然后从前向后枚举A,遍历到第i,求以i~n中所有a[i]为右边A的情况,假设有x个,然后二分左右和i~n包含相同数量a[i]的位置j,再求j+1~i-1中包含最多数量的相同数y,更新答案2*x+y
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=200100;
int a[N],f[210][N];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
for(int i=0;i<=n;++i){
for(int j=0;j<=200;++j) f[j][i]=0;
}
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}int ans=0;
for(int i=1;i<=n;++i){
f[a[i]][i]++;
for(int j=1;j<=200;++j){
f[j][i]+=f[j][i-1];
}
}
for(int i=1;i<=200;++i) ans=max(ans,f[i][n]);
for(int i=n;i>=1;--i){
int x=f[a[i]][n]-f[a[i]][i-1];
int j=lower_bound(f[a[i]]+1,f[a[i]]+n,x)-f[a[i]];
if(j>=i) continue;
int y=0;
for(int k=1;k<=200;++k){
y=max(y,f[k][i-1]-f[k][j]);
}
ans=max(ans,y+2*x);
}
cout<<ans<<endl;
}
return 0;
}