施工中(8/13)
题目链接:https://vjudge.net/contest/269632#overview
C - Flippy Sequence
队友写的,没看题
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1000010;
char a[N],b[N];
int c[N];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ll n;
scanf("%lld",&n);
scanf("%s",a);
scanf("%s",b);
int num=0;
for(int i=1;i<=n;i++)
{
if(a[i-1]==b[i-1])
c[i]=0;
else
{
c[i]=1;
if(c[i-1]==0)
num++;
}
}
if(num==0)
{
printf("%lld\n",n*(n+1)/2);
}
else if(num==1)
{
printf("%lld\n",2*(n-1));
}
else if(num==2)
{
printf("6\n");
}
else
{
printf("0\n");
}
}
return 0;
}
D - Magic Multiplication
如果能发现,枚举第一位后,后面的所有数都是固定的,就模拟了
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=2e5+5;
int a[MAXN],b[MAXN];
char s[MAXN];
int n,m,len,tim;
bool getb()
{
int tot=0;
tim++;
for(int &i=tim;i<=len&&tot<m;i++)
{
int now=s[i]-'0';
if(now%a[1]==0)
{
b[++tot]=now/a[1];
}
else
{
if(i==len) return false;
now=now*10+s[++i]-'0';
if(now%a[1]==0&&now/a[1]<=9)
{
b[++tot]=now/a[1];
}
else
{
return false;
}
}
}
if(b[1]==0) return false;
if(tot!=m) return false;
return true;
}
bool geta()
{
int tot=1;
int nowb=1;
for(int &i=tim;i<=len;i++,nowb++)
{
if(nowb>m) nowb-=m;
int now=s[i]-'0';
if(b[nowb]==0)
{
if(now==0)
{
if(nowb==1)
a[++tot]=0;
continue;
}
else return false;
}
if(now%b[nowb]==0)
{
if(nowb==1)
a[++tot]=now/b[nowb];
else if(now/b[nowb]!=a[tot])
return false;
}
else
{
if(i==len) return false;
now=now*10+s[++i]-'0';
if(now%b[nowb]==0&&now/b[nowb]<=9)
{
if(nowb==1)
a[++tot]=now/b[nowb];
else if(now/b[nowb]!=a[tot])
return false;
}
else
{
return false;
}
}
}
if(tim!=len+1) return false;
if(tot!=n) return false;
return true;
}
void print()
{
for(int i=1;i<=n;i++)
printf("%d",a[i]);
printf(" ");
for(int i=1;i<=m;i++)
printf("%d",b[i]);
puts("");
}
void solve()
{
scanf("%d%d",&n,&m);
scanf("%s",s+1);
len=strlen(s+1);
for(int i=1;i<=9;i++)
{
a[1]=i;
tim=0;
if(!getb())
{
continue;
}
if(!geta())
{
continue;
}
print();
return ;
}
puts("Impossible");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
E - Plants vs. Zombies
二分一个答案,然后从左到右贪心去做即可
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010;
ll a[N],b[N];
ll n,m;
ll judge(ll val)
{
ll all = 0;
ll ans = 0;
for(int i=1;i<=n;i++)
{
b[i] = val / a[i] + (val % a[i]>0?1:0);
all += b[i];
if(all > m)
return 0;
}
b[0]=0;b[n+1]=0;
for(int i=1;i<=n;i++)
{
ans += b[i-1]*2+1;
b[i]-=b[i-1]+1;
if(b[i] < 0 && i==n)
{
ans --;
}
b[i]=max(b[i],0ll);
b[i-1]=0;
if(ans > m)
return 0;
}
ans += b[n]*2;
if(ans>m)
return 0;
return 1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
ll l=0,r=1e18,mid;
ll ans=0;
while(l<=r)
{
mid = (l+r)/2;
if(judge(mid))
{
ans = mid;
l=mid+1;
}
else
r=mid-1;
}
printf("%lld\n",ans);
}
return 0;
}
F - Tournament
找规律即可
代码:
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int MAXN=1005;
int n,k;
int a[MAXN][MAXN];
void solve()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j]=0;
}
}
for(int i=1;i<=k;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==0)
{
if(j+i>n)
{
puts("Impossible");
return ;
}
a[i][j]=j+i;
a[i][j+i]=j;
for(int p=1;p<i;p++)
{
a[i][a[p][j]]=a[p][i+j];
a[i][a[p][i+j]]=a[p][j];
}
}
}
}
for(int i=1;i<=k;i++)
{
printf("%d",a[i][1]);
for(int j=2;j<=n;j++)
{
printf(" %d",a[i][j]);
}
puts("");
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
solve();
}
}
G - Repair the Artwork
首先发现,最多只有n方中不同的方法,然后dp[i][j]表示到i这个点,放了j种不同的方法,有多少方案数,然后在每个非0的地方来转移,容斥掉那些不合法的方案,n的四次方即可
代码:
#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int MAXN=105;
const int MOD=1e9+7;
int dp[MAXN][5105];
int a[MAXN],d[MAXN];
int n,m;
ll qpow(ll a,ll b)
{
ll ret=1;a%=MOD;
for(ll i=b;i;i>>=1,a=a*a%MOD)
{
if(i&1) ret=ret*a%MOD;
}
return ret;
}
void add(int &x,int y)
{
x=(1LL*x+y)%MOD;
}
void solve()
{
scanf("%d%d",&n,&m);
int lim=d[n];
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n+1;i++)
for(int j=0;j<=lim;j++)
dp[i][j]=0;
dp[0][0]=1;a[n+1]=1;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=lim;j++)
{
int w;
if(w=dp[i][j])
{
for(int k=i+1;k<=n+1;k++)
{
if(a[k]==1)
{
add(dp[k][j+d[k-i-1]],w);
break;
}
else if(a[k]==2)
{
add(dp[k][j+d[k-i-1]],MOD-w);
}
}
}
}
}
int ans=0;
for(int i=1;i<=lim;i++)
add(ans,qpow(i,m)*dp[n+1][i]%MOD);
printf("%d\n",ans);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
for(int i=1;i<=100;i++)
d[i]=i*(i+1)>>1;
while(T--)
{
solve();
}
return 0;
}
J - Books
水题(但是我不会啊。。。)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1000010;
ll a[N],b[N];
int main()
{
int T;
scanf("%d",&T);
while(T -->0)
{
int n,m;
int a_len=0;
ll tmp;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&tmp);
if(tmp==0)
m--;
else
{
a[a_len++] = tmp;
}
}
for(int i=a_len-1;i>=0;i--)
{
if(i==a_len-1)
b[i] = a[i];
else
b[i] = min(b[i+1],a[i]);
}
for(int i=1;i<a_len;i++)
{
a[i] += a[i-1];
}
if(a_len==m)
{
printf("Richman\n");
}
else if(m < 0)
{
printf("Impossible\n");
}
else if(m == 0)
{
printf("%lld\n",b[m]-1);
}
else
{
printf("%lld\n",a[m-1]+b[m]-1);
}
}
return 0;
}
L - Sub-cycle Graph
好像是个很牛逼的计数,队友在纸上画了一个小时搞出来的...
代码:
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int MAXN=100010;
const ll MOD = 1e9+7;
ll fac[MAXN],inv[MAXN];
ll f2[MAXN];
ll qpow(ll a,ll b)
{
ll ret=1;a%=MOD;
for(ll i=b;i;i>>=1,a=a*a%MOD)
if(i&1) ret=ret*a%MOD;
return ret;
}
void init()
{
fac[0]=1;
for(int i=1;i<MAXN;i++)//阶乘打表
fac[i]=fac[i-1]*i%MOD;
for(int i=0;i<MAXN;i++)
f2[i] = qpow(qpow(2,i),MOD-2);
inv[0]=1;inv[MAXN-1]=qpow(fac[MAXN-1],MOD-2);//费马小定理求逆元
for(int i=MAXN-2;i>=1;i--)
inv[i]=inv[i+1]*(i+1)%MOD;
}
ll C(ll n,ll m)
{
if(m>n||m<0) return 0;
ll s1=fac[n],s2=inv[n-m]*inv[m]%MOD;
return s1*s2%MOD;
}
int main()
{
init();
int T;
scanf("%d",&T);
while(T--)
{
ll n,m;
scanf("%lld%lld",&n,&m);
if(m==0)
{
puts("1");
continue;
}
if(m>n)
{
printf("0\n");
}
else if(m==n)
{
if(n==2)
printf("1\n");
else
printf("%lld\n",(fac[n-1]*f2[1]) % MOD);
}
else
{
ll ans = 0;
for(ll i=max(0ll,n-(m*2));i<=n-(m+1);i++)
{
ll tmp = fac[n-i];
ll p = C(m-1,n-i-m-1);
tmp*=p;tmp%=MOD;
p = inv[n-i-m];
tmp*=p;tmp%=MOD;
p = f2[n-i-m];
tmp*=p;tmp%=MOD;
//printf("i=%lld %lld\n",i,tmp);
ans+=(tmp*C(n,i)) % MOD;
ans%=MOD;
}
printf("%lld\n",ans);
}
}
}
M - Function and Function
真的水题,模拟就行了
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int judge(int x)
{
switch(x)
{
case 0:return 1;
case 1:return 0;
case 2:return 0;
case 3:return 0;
case 4:return 1;
case 5:return 0;
case 6:return 1;
case 7:return 0;
case 8:return 2;
case 9:return 1;
}
return 0;
}
int f(int x)
{
if(x==0) return 1;
int ret=0;
while(x)
{
ret+=judge(x%10);
x/=10;
}
return ret;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int x,k;
scanf("%d%d",&x,&k);
for(int i=1;i<=k;i++)
{
x=f(x);
if(x==0)
{
int res=k-i;
if(res%2) x=1;
else x=0;
break;
}
}
printf("%d\n",x);
}
return 0;
}