A.Floor Number
对于第一层要分开来算;当不整除时注意加一。
#include <bits/stdc++.h>
using namespace std;
int T;
int n,x,ans;
int main(){
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&x);
n-=2; ans=1;
if (n<=0)
{
printf("%d\n",ans);
continue;
}
if (n%x==0) ans+=n/x;
else ans+=n/x+1;
printf("%d\n",ans);
}
return 0;
}
B.Symmetric Matrix
只要有一个正方形满足:b=c即可。
#include <bits/stdc++.h>
using namespace std;
int T;
int n,m,a,b,c,d;
int main(){
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
bool jay=false;
for (register int i=1; i<=n; ++i)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
if (b==c) jay=true;
}
if (m%2==1) {puts("NO"); continue;}
if (jay) puts("YES");
else puts("NO");
}
return 0;
}
C. Increase and Copy
我们来考虑一下最后的若干个数的最优形式:假设现在我们经过a-1次操作,构造出了一个a,那么我们现在想得到一个b,设(b>a),所以我们现在需要1+(b-a)次变化,可以得到数列:ab。 (先复制一次a,然后将那个复制的a操作b-a次变成b)
那么如果我直接将a操作b-a次变成b,然后再复制一次b,那么我们在同样进行1+(b-a)次操作的情况下,可以得到数列:bb。
这可以说明,最终的数列最优的情况是所有位置的数均相同的。
所以我们从1-n枚举这个最优位置的数,就可以计算出:从1到这个数要经过几次操作,和这个数要复制几次。
根据基本不等式可以得知我们操作数是在sqrt(n)附近,所以真实复杂度为O(T*sqrt(n))。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int T;
int n,ans;
signed main(){
scanf("%lld",&T);
while (T--)
{
ans=2e9;
scanf("%lld",&n);
for (register int i=1; i<=n; ++i)
{
if (i-1>=ans) break;
ans=min(ans,(i-1)+(n-1)/i);
}
printf("%lld\n",ans);
}
return 0;
}
D. Non-zero Segments
从右往左考虑,若在[1,i]区间内,出现了字段和为0的情况,那么肯定是在i-1与i之间分割一次(即加一个超级大数或超级小数)。因为这样分割,之前的数,对后面的影响最小,只有a[i]会对后面产生影响。
那么对于字段和为0的判断,我们可以用map来存储某个数值是否出现过。
注意初始值,map[0]=1。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,l,r,mid,ans,sum;
int a[N];
map<int,int>mp;
signed main(){
scanf("%lld",&n);
for (register int i=1; i<=n; ++i) scanf("%lld",&a[i]);
mp[0]=1;
int now=0;
for (register int i=1; i<=n; ++i)
{
if (mp[now+a[i]])
{
sum++;
mp.clear();
mp[0]=1;
mp[a[i]]=1;
now=a[i];
}
else mp[now+a[i]]=1,now+=a[i];
}
printf("%lld\n",sum);
return 0;
}
E. Rock, Paper, Scissors
赢得最多的情况很容易计算,那么赢得最少的情况是什么呢?肯定不是:总和减去对方赢得最多的情况。
我们需要对方去尽量抵消Alice的出拳数量,无论是对方赢还是平,均是符合要求的。
设六个数为a[1],a[2],a[3],b[1],b[2],b[3]。
那么b[1]可以抵消a[1],a[2];b[2]可以抵消a[2],a[3];b[3]可以抵消a[3],a[1]。
所以我们枚举抵消操作的顺序,对ans不断取min即可。
#include <bits/stdc++.h>
using namespace std;
int n,ans,tot,anss;
int a[10],b[10],d[10],aa[10],bb[10];
bool vis[10];
struct node{int b,a;}c[10];
void dfs(int x)
{
int sum=0;
memcpy(aa,a,sizeof(aa)); memcpy(bb,b,sizeof(bb));
for (register int i=1; i<=tot; ++i)
{
int minn=min(bb[c[d[i]].b],aa[c[d[i]].a]);
bb[c[d[i]].b]-=minn; aa[c[d[i]].a]-=minn;
sum+=minn;
}
ans=min(ans,n-sum);
if (x==7)
{
return;
}
for (register int i=1; i<=6; ++i)
if (!vis[i])
{
tot++;
d[tot]=i;
vis[i]=true;
dfs(x+1);
tot--;
vis[i]=false;
}
dfs(x+1);
}
int main(){
scanf("%d",&n);
for (register int i=1; i<=3; ++i) scanf("%d",&a[i]);
for (register int i=1; i<=3; ++i) scanf("%d",&b[i]);
anss=min(a[1],b[2])+min(a[2],b[3])+min(a[3],b[1]);
c[1]=(node){1,1};
c[2]=(node){1,2};
c[3]=(node){2,2};
c[4]=(node){2,3};
c[5]=(node){3,3};
c[6]=(node){3,1};
ans=n;
dfs(1);
printf("%d %d\n",ans,anss);
return 0;
}
F. Number of Subsequences
枚举每一个’?‘和’b’,然后根据前缀和可以得到:[1,i-1]的’a’,’?‘和[i+1,n]的’c’,’?'个数。
当我们取i位置作为b时,[1,i-1]可以选’a’也可以选’?’;[i+1,n]可以选’c’也可以选’?’,所以共有四种情况。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,MOD=1e9+7;
int n,ans;
int sum[N][5];
char str[N];
inline int query(int l,int r,int id)
{
if (l>r) return 0;
return sum[r][id]-sum[l-1][id];
}
inline int pow(int a,int nn)
{
if (nn<0) return 0ll;
int res=1ll;
while (nn)
{
if (nn&1ll) res=res*a%MOD;
a=a*a%MOD;
nn>>=1ll;
}
return res;
}
signed main(){
scanf("%lld",&n);
scanf("%s",str+1);
for (register int i=1; i<=n; ++i)
{
for (register int j=1; j<=4; ++j) sum[i][j]=sum[i-1][j];
if (str[i]=='?') sum[i][4]++;
else sum[i][str[i]-'a'+1]++;
}
for (register int i=1; i<=n; ++i)
if (str[i]=='b' || str[i]=='?')
{
int a=query(1,i-1,4),b=query(i+1,n,4);
ans=(ans+query(1,i-1,4)*query(i+1,n,4)%MOD*pow(3ll,a+b-2)%MOD)%MOD;
ans=(ans+query(1,i-1,4)*query(i+1,n,3)%MOD*pow(3ll,a+b-1)%MOD)%MOD;
ans=(ans+query(1,i-1,1)*query(i+1,n,4)%MOD*pow(3ll,a+b-1)%MOD)%MOD;
ans=(ans+query(1,i-1,1)*query(i+1,n,3)%MOD*pow(3ll,a+b)%MOD)%MOD;
}
printf("%lld\n",ans);
return 0;
}