这个应该是第一场有英文的atcoder吧??不过题解却没有英文的。。。
从前往后慢慢做。。。
C こだわり者いろはちゃん / Iroha's Obsession
数据范围这么小,直接暴力
#include <bits/stdc++.h>
using namespace std;
bool rec[10];
bool check(int num)
{
while(num)
{
if(rec[num%10]) return false;
num /= 10;
}
return true;
}
int main()
{
int n,k,num;
cin >> n >> k;
for(int i = 0; i < k; ++i)
{
cin >> num;
rec[num] = true;
}
while(true)
{
if(check(n))
{
cout << n << endl;
break;
}
++n;
}
return 0;
}
####D - いろはちゃんとマス目 / Iroha and a Grid 在H * W的矩阵中,左下角有一个A * B的矩阵不能走,求左上角走到右下角方法数。 建议一道题: 51nod 1486 大大走格子 这题容斥原理,比上边那个题简单。没有障碍时,总方法数是C(H+W-2,H-1)总方法数 求出来所有走过障碍处的走法, 用总的减掉就好了。 走过障碍处的方法数就是走到A*B矩阵上方一行的时候,选择向下走,就是非法的。减掉这些就好。 ``` #include
LL modPow(LL a, LL b)
{
LL ret = 1;
while(b)
{
if(b&1) ret = reta%mod;
a = aa%mod;
b >>= 1;
}
return ret;
}
void init()
{
fac[0] = 1;
inv[0] = 1;
for(LL i = 1; i <= H+W; ++i)
fac[i] = fac[i-1]i%mod;
inv[H+W] = modPow(fac[H+W],mod-2);
for(LL i = H+W-1; i >= 1; --i)
inv[i] = (inv[i+1](i+1))%mod;
}
LL C(LL n, LL m)
{
LL ret = (fac[n]inv[m]%mod)inv[n-m]%mod;
return ret;
}
int main()
{
cin >> H >> W >> A >> B;
init();
LL res = C(H+W-2,H-1);
LL minu = 0;
for(int i = 1; i <= B; ++i)
minu = (minu + C(H-A+i-2, H-A-1)*C(A+W-i+1-2,A-1)%mod)%mod;
cout << ((res-minu)%mod+mod)%mod << endl;
return 0;
}
<hr/>
####E - 和風いろはちゃん / Iroha and Haiku
没有找到英文题解和中文题解。。。。。
这个题,感觉有点难。起初思路是算组合数,毕竟数据范围很小,算出1-7的拆分数的每种情况,然后算组合数和排列呗。
算了好久,不知道哪里错了,看了http://imulan.hatenablog.jp/entry/2016/07/24/233524这个题解,才发现有地方重复计算了。
然后又看了https://kimiyuki.net/blog/2016/07/23/arc-058-e/这个题解,还有官方题解,理解的模模糊糊。
比如说1用1表示,2用10表示,3用100表示,即i用(1<<(i-1))表示。
在这里是计算出不合法的数量,总数量-不合法数量=结果。
比如说要的X,Y,Z是5,7,5,表示这个结果的状态就是10000100000010000。
然后枚举每种情况。。。
还是有点懵。。。路过的大佬求解答。。
感觉日语翻译成英语比翻译成汉语读着顺一点。。
include
include
include
typedef long long ll;
using namespace std;
const int mod = 1e9+7;
ll dp[41][1<<18];
int main()
{
int n, x, y, z;
scanf("%d%d%d%d", &n, &x, &y, &z);
int l = x+y+z-1;
int mask = (1<<l)-1;
int limit = (1<<l);
int ok = (1 << (x+y+z-1)) | (1 << (y+z-1)) | (1 << (z-1));
dp[0][0] = 1;
for(int i = 0; i < n; ++i)
{
for(int s = 0; s < limit; ++s)
{
for(int a = 1; a < 11; ++a)
{
int t = (s << a) | (1 << (a-1));
if ((ok&t) == ok) continue;
//旧的状态向新的状态转移
(dp[i+1][t & mask] += dp[i][s]) %= mod;
}
}
}
ll ans = 1;
for(int i = 0; i < n; ++i)
ans = ans * 10 % mod;
//去掉每种状态的不合法数量
for(int s = 0; s < limit; ++s)
ans -= dp[n][s];
ans = (ans % mod + mod) % mod;
printf("%lld
", ans);
return 0;
}
<hr/>
####F - 文字列大好きいろはちゃん / Iroha Loves Strings
------不会