给定abc三个字符串,c的每一位都必须与a或者b的对应位交换,问交换后的a和b是否可能相等
由于c的每一位都必须交换,而交换后都要与另一个字符串的对应位比较,所以只需循环一遍,判断每一位c是否都能与a或者b对应位中的一个相等即可
#include
#include
using namespace std;
int main()
{ long N,i;
string a,b,c;
bool t;
scanf("%ld",&N);
while(N--){
cin>>a>>b>>c;
t=true;
for(i=0;i<a.length();i++)
if(c[i]!=a[i]&&c[i]!=b[i]){
t=false;
break;
}
if(t)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
给定一串数列,要求将其中的所有-1替换为同一个数k,求k使得替换后的整个数列相邻位之差的绝对值的最大值最小
因为全部-1都替换为k,所以当-1两边的数与k的差值最小时,满足条件的k一定等于-1两边的(最大值+最小值)/2,替换后统计一遍即可
#include
#include
#include
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define abs(i) (((i)>0)?(i):-(i))
#define def 100010
#define ll long long
using namespace std;
ll a[def];
int main()
{ ll N,n,i,num,ans,minn,maxx;
scanf("%lld",&N);
while(N--){
memset(a,0,sizeof(a));
scanf("%lld",&n);
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
minn=~(1<<31);
maxx=0;
for(i=1;i<=n;i++)
if(a[i]==-1){
if(i>1&&a[i-1]!=-1){
minn=min(minn,a[i-1]);
maxx=max(maxx,a[i-1]);
}
if(i<n&&a[i+1]!=-1){
minn=min(minn,a[i+1]);
maxx=max(maxx,a[i+1]);
}
}
num=(maxx+minn)/2;
for(i=1;i<=n;i++)
if(a[i]==-1)
a[i]=num;
ans=0;
for(i=1;i<n;i++)
ans=max(ans,abs(a[i+1]-a[i]));
if(minn!=~(1<<31))
printf("%lld %lld\n",ans,num);
else
printf("%lld %lld\n",ans,0ll);
}
return 0;
}
定义 f ( s ) f(s) f(s)为字符串s包含1的字串的个数,给定n和m,构造一个n位的01字符串,其中1的个数为m个,使得 f ( s ) f(s) f(s)最大
用组合数可以推出,一个字符串的子串个数为 C n + 1 2 = n ∗ ( n + 1 ) / 2 C^2_{n+1}=n*(n+1)/2 Cn+12=n∗(n+1)/2
由于只含0的字串比含1的字串统计更方便,所以考虑0的摆放位置。问题转化为:一共 ( n − m ) (n-m) (n−m)个0,分成 m + 1 m+1 m+1份,使每一份字串个数最少,剩下的1就放在产生的 m m m个空位里。
易证一个结论: k ∗ ( k + 1 ) / 2 ∗ 2 < ( k − 1 ) ∗ k / 2 + ( k + 1 ) ∗ ( k + 2 ) / 2 k*(k+1)/2*2<(k-1)*k/2+(k+1)*(k+2)/2 k∗(k+1)/2∗2<(k−1)∗k/2+(k+1)∗(k+2)/2
所以均分产生的字串数量最少,如果无法完全均分,就尽量均分。
最终答案就是:总子串数-所有只含0的字串数
#include
#define ll long long
int main()
{ ll N,n,m,p,r;
scanf("%lld",&N);
while(N--){
scanf("%lld%lld",&n,&m);
p=(n-m)/(m+1);
r=(n-m)%(m+1);
printf("%lld\n",n*(n+1)/2-r*(p+1)*(p+2)/2-(m+1-r)*p*(p+1)/2);
}
return 0;
}