PG BATTLE 2022 解答例一覧
AtCoder社による解答はC++のものとなります。
JavaおよびPythonによる解答例はPG BATTLE運営が用意したものとなりますので、ご了承ください。
ましゅまろ(Marshmallow)
難易度1(Level1)
電話番号(Phone Number)
難易度2(Level2)
等式(Equality)
難易度3(Level3)
試験の成績(Examination Results)
難易度5(Level5)
沈黙(Silence)
ましゅまろ(難易度1)電話番号
Marshmallow(Level1)/ Phone Number
C++
#include <iostream>
using namespace std;
int main(void)
{
string s;
cin >> s;
cout << "81" << s.substr(1) << endl;
return 0;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String S = sc.next();
System.out.println("8190" + S.substring(3));
}
}
Python
S = input()
print(f'8190{S[3:]}')
ましゅまろ(難易度2)等式
Marshmallow(Level2)/ Equality
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
int N;
cin>>N;
vector<int> a(N+1);
vector<char> op(N);
for(int i=0;i<N+1;i++){
cin>>a[i];
if(i!=N)cin>>op[i];
}
int sum = -1;
while(a.size()>0){
int t = a.back();
a.pop_back();
while(true){
if(a.size()==0)break;
if(op.back()=='+'){
op.pop_back();
t += a.back();
a.pop_back();
}
else{
op.pop_back();
break;
}
}
if(sum==-1)sum = t;
else if(sum!=t){
cout<<"No"<<endl;
return 0;
}
}
cout<<"Yes"<<endl;
return 0;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int sum = -1;
int tmp = sc.nextInt();
for (int i = 0; i < N; i++) {
String op = sc.next();
if (op.equals("=")) {
if (sum == -1) {
sum = tmp;
}
if (sum != tmp) {
System.out.println("No");
return;
}
tmp = sc.nextInt();
} else {
tmp += sc.nextInt();
}
}
if (sum != tmp) {
System.out.println("No");
} else {
System.out.println("Yes");
}
}
}
Python
N = int(input())
values = list(map(eval, input().split("=")))
values.sort()
print("Yes" if values[0] == values[-1] else "No")
ましゅまろ(難易度3)試験の成績
Marshmallow(Level3)/ Examination Results
C++
#include <iostream>
#include <map>
#include <vector>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
int main() {
ll N, p, q;
cin >> N >> p >> q;
map<int, vector<int>> m;
rep(i, N) {
int a, b;
cin >> a >> b;
m[-(a * p + b * q)].push_back(i);
}
vector<int> rank(N);
int r = 1;
for (auto& [_, v] : m) {
for (auto& i : v) rank[i] = r;
r += v.size();
}
for (auto& x : rank) cout << x << "\n";
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int p = sc.nextInt();
int q = sc.nextInt();
TreeMap<Integer, List<Integer>> scores = new TreeMap<Integer, List<Integer>>();
for (int i = 0; i < N; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
int score = p * a + q * b;
if (!scores.containsKey(score)) {
scores.put(score, new ArrayList<Integer>());
}
scores.get(score).add(i);
}
int[] ranks = new int[N];
int r = 1;
for (int score : scores.descendingKeySet()) {
for (int student : scores.get(score)) {
ranks[student] = r;
}
r += scores.get(score).size();
}
StringJoiner sj = new StringJoiner("\n");
for (int rank : ranks) {
sj.add(String.valueOf(rank));
}
System.out.println(sj.toString());
}
}
Python
N, p, q = list(map(int, input().split()))
scores = []
for i in range(N):
a, b = list(map(int, input().split()))
scores.append((p * a + q * b, i))
scores.sort(reverse=True)
rank = [-1] * N
rank[scores[0][1]] = 1
for i in range(1, N):
if scores[i][0] == scores[i-1][0]:
rank[scores[i][1]] = rank[scores[i-1][1]]
else:
rank[scores[i][1]] = i + 1
print(*rank, sep="\n")
ましゅまろ(難易度5)沈黙
Marshmallow(Level5)/ Silence
C++
#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace atcoder;
using mint = modint998244353;
using namespace std;
mint combi[12][12];
void dfs(int c,long long s,mint v,vector<long long> a,vector<long long> b,map<long long,mint> &mp){
if(c==a.size()){
mp[s] += v;
return;
}
for(int i=0;i<=10;i++){
for(int j=0;j<=1;j++){
dfs(c+1,s+a[c]*i+b[c]*j,v*combi[10][i],a,b,mp);
}
}
}
int main() {
combi[0][0] = 1;
for(int i=0;i<10;i++){
for(int j=0;j<=i;j++){
combi[i+1][j] += combi[i][j];
combi[i+1][j+1] += combi[i][j];
}
}
int N;
cin>>N;
vector<long long> a(N/2),b(N/2),c((N+1)/2),d((N+1)/2);
long long sum = 0;
for(int i=0;i<N/2;i++){
cin>>a[i]>>b[i];
sum += a[i]*10 + b[i];
}
for(int i=0;i<(N+1)/2;i++){
cin>>c[i]>>d[i];
sum += c[i]*10 + d[i];
}
if(sum%2==1){
cout<<0<<endl;
return 0;
}
map<long long,mint> ma,mb;
dfs(0,0,1,a,b,ma);
dfs(0,0,1,c,d,mb);
mint ans = 0;
for(auto x:ma){
ans += x.second * mb[sum/2-x.first];
}
cout<<ans.val()<<endl;
return 0;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
long MOD = 998244353;
int[] comb = new int[11];
comb[0] = 1;
for (int i = 1; i < 11; i++) {
comb[i] = comb[i-1] * (11-i);
comb[i] /= i;
}
Map<Integer, Map<Long, Long>> dp = new HashMap<Integer, Map<Long, Long>>();
dp.put(0, new HashMap<Long, Long>() );
dp.put(1, new HashMap<Long, Long>() );
for (int i = 0; i < N; i++) {
Map<Long, Long> ndp = new HashMap<Long, Long>();
long a = sc.nextLong();
long b = sc.nextLong();
for (int j = 0; j <= 10; j++) {
long t = (2*j - 10) * a;
for (int k = -1; k <= 1; k++) {
if (k == 0) continue;
long k1 = t + b * k;
long v1 = comb[j];
for (long k2 : dp.get(i%2).keySet()) {
long pv = ndp.containsKey(k1+k2) ? ndp.get(k1+k2) : 0;
long v2 = dp.get(i%2).get(k2);
ndp.put(k1+k2, (pv+v1*v2)%MOD);
}
}
}
dp.put(i%2, ndp);
}
long ans = 0;
for (long k : dp.get(0).keySet()) {
if (dp.get(1).containsKey(-k)) {
ans += dp.get(0).get(k) * dp.get(1).get(-k);
ans %= MOD;
}
}
System.out.println(ans);
}
}
Python
from collections import Counter
N = int(input())
MOD = 998244353
comb = [1] * 11
for i in range(1, 11):
comb[i] = comb[i-1] * (11-i)
comb[i] //= i
dp = [Counter({0: 1}) for _ in range(2)]
for i in range(N):
ndp = Counter()
a, b = list(map(int, input().split()))
for j in range(11):
t = (2*j - 10) * a
for k in [-1, 1]:
k1 = t + b * k
v1 = comb[j]
for k2, v2 in dp[i%2].most_common():
ndp[k1+k2] += v1 * v2
ndp[k1+k2] %= MOD
dp[i%2] = ndp
ans = 0
for k, v in dp[0].most_common():
ans += v * dp[1][-k]
ans %= MOD
print(ans)
せんべい(Senbei)
難易度2(Level2)
せんべい(Rice Cracker)
難易度3(Level3)
食品の区別(Distinguish the Foods)
難易度4(Level4)
区間の削除(Delete Intervals)
難易度6(Level6)
都市の合併(Municipal Merger)
せんべい(難易度2)せんべい
Senbei(Level2)/ Rice Cracker
C++
#include <iostream>
#include <numeric>
#include <vector>
using namespace std;
int main() {
int N, Q;
cin >> N >> Q;
vector<int> senbei(N + 1, 0);
for (int q = 1; q <= Q; q++) {
int L, R;
cin >> L >> R;
for (int j = L; j <= R; j++) senbei[j] ^= 1;
}
cout << accumulate(begin(senbei), end(senbei), 0) << endl;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int Q = sc.nextInt();
int[] reversed = new int[N];
for (int i = 0; i < Q; i++) {
int L = sc.nextInt();
int R = sc.nextInt();
for (int j = L - 1; j < R; j++) {
reversed[j] ^= 1;
}
}
int ans = 0;
for (int i = 0; i < N; i++) {
ans += reversed[i];
}
System.out.println(ans);
}
}
Python
N, Q = list(map(int, input().split()))
is_reversed = [0] * N
for _ in range(Q):
L, R = list(map(int, input().split()))
for i in range(L-1, R):
is_reversed[i] ^= 1
print(sum(is_reversed))
せんべい(難易度3)食品の区別
Senbei(Level3)/ Distinguish the Foods
C++
#include<bits/stdc++.h>
using namespace std;
using pi=pair<int,int>;
int main(){
int n;
cin >> n;
vector<pi> pv(3*n);
for(int i=0;i<3*n;i++){
cin >> pv[i].first;
pv[i].second=i+1;
}
sort(pv.begin(),pv.end());
vector<int> res;
for(int i=n;i<2*n;i++){
res.push_back(pv[i].second);
}
sort(res.begin(),res.end());
for(auto &nx : res){
cout << nx << "\n";
}
return 0;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int[] foods = new int[3*N];
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < 3*N; i++) {
int a = sc.nextInt();
foods[i] = a;
map.put(a, i + 1);
}
Arrays.sort(foods);
int[] ans = new int[N];
for (int i = 0; i < N; i++) {
ans[i] = map.get(foods[N+i]);
}
Arrays.sort(ans);
StringJoiner sj = new StringJoiner("\n");
for (int i : ans) {
sj.add(String.valueOf(i));
}
System.out.println(sj.toString());
}
}
Python
N = int(input())
A = list(enumerate(map(int, input().split())))
A.sort(key=lambda x: (x[1], x[0]))
print(*[i+1 for i, _ in sorted(A[N:2*N])], sep="\n")
せんべい(難易度4)区間の削除
Senbei(Level4)/ Delete Intervals
C++
#include <iostream>
#include <stack>
using namespace std;
typedef long long ll;
ll n;
ll a[500005];
int main(void)
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
ll ans = 0;
for(int i = 1; i <= n; i++) ans += a[i];
stack<ll> stk;
stk.push(-1);
for(int i = n; i >= 1; i--){
stk.push(a[i]);
if(stk.top() == 1){
for(int j = 1; ; j++){
if(stk.top() != j) break;
ans -= j;
stk.pop();
}
}
}
cout << ans << endl;
return 0;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
LinkedList<Integer> A = new LinkedList<Integer>();
for (int i = 0; i < N; i++) {
A.add(sc.nextInt());
}
LinkedList<Integer> B = new LinkedList<Integer>();
for (int i = 0; i < N; i++) {
int a = A.pollLast();
if (a == 1) {
int k = 2;
while (!B.isEmpty() && B.getFirst() == k) {
B.pop();
k += 1;
}
} else {
B.push(a);
}
}
System.out.println(B.stream().mapToLong(v -> v).sum());
}
}
Python
N = int(input())
A = list(map(int, input().split()))
B = []
while A:
a = A.pop()
if a == 1:
k = 2
while B and B[-1] == k:
B.pop()
k += 1
else:
B.append(a)
print(sum(B))
せんべい(難易度6)都市の合併
Senbei(Level6)/ Municipal Merger
C++
#include <iostream>
#include <vector>
using namespace std;
#include "atcoder/modint.hpp"
using mint = atcoder::modint998244353;
struct Binomial {
vector<mint> fac, invfac, inv;
Binomial(int n) : fac(n + 1), invfac(n + 1), inv(n + 1) {
fac[0] = invfac[0] = inv[0] = 1;
for (int i = 1; i <= n; i++) fac[i] = fac[i - 1] * i;
invfac[n] = fac[n].inv();
for (int i = n - 1; i >= 0; i--) {
invfac[i] = invfac[i + 1] * (i + 1);
inv[i + 1] = invfac[i + 1] * fac[i];
}
}
mint operator()(int n, int r) {
if (n < 0 || r < 0 || n < r) return 0;
return fac[n] * invfac[n - r] * invfac[r];
}
} C{10000};
#include "atcoder/convolution.hpp"
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define sz(v) ((int)(v).size())
vector<mint> add(const vector<mint>& a, const vector<mint>& b) {
vector<mint> c(max(sz(a), sz(b)));
rep(i, sz(a)) c[i] += a[i];
rep(i, sz(b)) c[i] += b[i];
return c;
}
vector<mint> mul(const vector<mint>& a, const vector<mint>& b) {
return atcoder::convolution(a, b);
}
int main() {
int N, K;
cin >> N >> K;
vector<int> a(N);
rep(i, N) cin >> a[i];
vector g(N, vector<int>{});
rep(i, N - 1) {
int A, B;
cin >> A >> B;
--A, --B;
g[A].push_back(B);
g[B].push_back(A);
}
// (i が根の場合の MGF) + 1
vector<vector<mint>> dp(N);
{
auto dfs = [&](auto rc, int c, int p = -1) -> vector<mint> {
vector<mint> f(K + 1);
mint buf = 1;
for (int i = 0; i <= K; i++, buf *= a[c]) f[i] = buf * C.invfac[i];
for (auto& d : g[c]) {
if (d == p) continue;
auto fc = rc(rc, d, c);
f = mul(f, fc);
f.resize(K + 1);
}
f[0] += 1;
return dp[c] = f;
};
dfs(dfs, 0);
}
vector<mint> ans(N);
vector<mint> I(K + 1);
I[0] = 1;
{
auto dfs = [&](auto rc, int c, int p, vector<mint> dat) -> void {
vector<mint> f(K + 1);
mint buf = 1;
for (int i = 0; i <= K; i++, buf *= a[c]) f[i] = buf * C.invfac[i];
if (dat.empty()) dat = I;
f = mul(f, dat);
f.resize(K + 1);
vector<int> cid{p};
vector<vector<mint>> cval{f};
for (auto& d : g[c]) {
if (d == p) continue;
cid.push_back(d);
cval.push_back(dp[d]);
}
vector<vector<mint>> L(sz(cval) + 1), R(sz(cval) + 1);
L[0] = R.back() = I;
rep(i, sz(cval)) {
L[i + 1] = mul(L[i], cval[i]);
L[i + 1].resize(K + 1);
}
for (int i = sz(cval); i--;) {
R[i] = mul(R[i + 1], cval[i]);
R[i].resize(K + 1);
}
ans[c] = L.back()[K] * C.fac[K];
int i = 1;
for (auto& d : g[c]) {
if (d == p) continue;
vector<mint> s = mul(L[i], R[i + 1]);
s.resize(K + 1);
s[0] += 1;
rc(rc, d, c, s);
i++;
}
};
dfs(dfs, 0, -1, {});
}
for (auto& x : ans) cout << x.val() << "\n";
}
かつおぶし(Katsuobushi)
難易度3(Level3)
等差数列(Arithmetic Progression)
難易度4(Level4)
反射(Reflection)
難易度5(Level5)
模様(Pattern)
難易度6(Level6)
二歩(Two Pawns)
かつおぶし(難易度3)等差数列
Katsuobushi(Level3)/ Arithmetic Progression
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
int N;
cin>>N;
vector<int> b(N);
for(int i=0;i<N;i++)cin>>b[i];
sort(b.begin(),b.end());
int d = (b[N-1] - b[0])/N;
for(int i=0;i<N;i++){
if(b[i]+d!=b[i+1]){
cout<<b[i]+d<<endl;
return 0;
}
}
return 0;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
long[] B = new long[N];
long sum = 0;
for (int i = 0; i < N; i++) {
B[i] = sc.nextLong();
sum += B[i];
}
Arrays.sort(B);
System.out.println((B[0]+B[N-1]) * (N+1) / 2 - sum);
}
}
Python
N = int(input())
B = list(map(int, input().split()))
B.sort()
print((B[0]+B[-1]) * (N+1) // 2 - sum(B))
かつおぶし(難易度4)反射
Katsuobushi(Level4)/ Reflection
C++
#include <iostream>
#include <tuple>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
ll w, h, t;
ll sx, sy, tx, ty;
map<ll, ll> mp;
ll check(ll x, ll y, ll rx, ll ry)
{
x = (x%(2*w)+(2*w)) % (2*w);
y = (y%(2*h)+(2*h)) % (2*h);
if(x == rx && y == ry) return 1;
else return 0;
}
ll calc(ll rx, ll ry)
{
ll ret = 0;
for(ll x = -t; x <= t; x++){
ll r = t*t-x*x;
if(mp.count(r) == 0) continue;
ll y = mp[r];
ret += check(sx+x, sy+y, rx, ry);
if(y > 0) ret += check(sx+x, sy-y, rx, ry);
}
return ret;
}
int main(void)
{
cin >> w >> h >> t;
cin >> sx >> sy >> tx >> ty;
for(ll i = 0; i <= 200000; i++) mp[i*i] = i;
ll ans = calc(tx, ty);
ans += calc(2*w-tx, ty);
ans += calc(2*w-tx, 2*h-ty);
ans += calc(tx, 2*h-ty);
cout << ans << endl;
return 0;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int W = sc.nextInt();
int H = sc.nextInt();
long T = sc.nextInt();
int sx = sc.nextInt();
int sy = sc.nextInt();
int tx = sc.nextInt();
int ty = sc.nextInt();
int ans = 0;
for (long dx = -T; dx <= T; dx++) {
if ((sx + dx + T * 2 * W) % (2 * W) != tx && (sx + dx + T * 2 * W) % (2 * W) != 2 * W - tx) continue;
long sq_dy = T * T - dx * dx;
if (sq_dy < 0 || Math.sqrt(sq_dy) % 1 != 0) continue;
long abs_dy = (long) Math.sqrt(sq_dy);
if (abs_dy != 0) {
ans += (sy + abs_dy + T * 2 * H) % (2 * H) == ty ? 1 : 0;
ans += (sy + abs_dy + T * 2 * H) % (2 * H) == 2 * H - ty ? 1 : 0;
ans += (sy - abs_dy + T * 2 * H) % (2 * H) == ty ? 1 : 0;
ans += (sy - abs_dy + T * 2 * H) % (2 * H) == 2 * H - ty ? 1 : 0;
} else {
ans += sy % (2 * H) == ty ? 1 : 0;
ans += sy % (2 * H) == 2 * H - ty ? 1 : 0;
}
}
System.out.println(ans);
}
}
Python
from math import sqrt
W, H, T = list(map(int, input().split()))
sx, sy = list(map(int, input().split()))
tx, ty = list(map(int, input().split()))
# 総移動距離の2乗 = x方向の移動距離の2乗 + y方向の移動距離の2乗
sq_T = T**2
ans = 0
for dx in range(-T, T+1):
if (sx + dx) % (2 * W) != tx and (sx + dx) % (2 * W) != 2 * W - tx:
continue
sq_dy = sq_T - dx**2
if sq_dy < 0:
continue
abs_dy = sqrt(sq_dy)
if abs_dy:
ans += (sy + abs_dy) % (2 * H) == ty
ans += (sy + abs_dy) % (2 * H) == 2 * H - ty
ans += (sy - abs_dy) % (2 * H) == ty
ans += (sy - abs_dy) % (2 * H) == 2 * H - ty
else:
ans += sy % (2 * H) == ty
ans += sy % (2 * H) == 2 * H - ty
print(ans)
かつおぶし(難易度5)模様
Katsuobushi(Level5)/ Pattern
C++
#include<bits/stdc++.h>
using namespace std;
int lucas(int n,int r){
n^=((1<<31)-1);
if(n&r){return 0;}
return 1;
}
int main(){
int n,m;
cin >> n >> m;
string s,t;
cin >> s >> t;
int k;
cin >> k;
vector<int> x(k),y(k);
for(int i=0;i<k;i++){
cin >> x[i] >> y[i];
x[i]--;y[i]--;
if(y[i]==0){
cout << s[x[i]] << "\n";
}
else if(x[i]==0){
cout << t[y[i]] << "\n";
}
else{
int res=0;
for(int j=1;j<=x[i];j++){
if(s[j]=='0'){continue;}
int d=x[i]-j;
int r=y[i]-1;
res+=lucas(d+r,r);
}
for(int j=1;j<=y[i];j++){
if(t[j]=='0'){continue;}
int d=x[i]-1;
int r=y[i]-j;
res+=lucas(d+r,r);
}
cout << res%2 << "\n";
}
}
return 0;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int M = sc.nextInt();
char[] cS = sc.next().toCharArray();
char[] cT = sc.next().toCharArray();
int[] S = new int[N];
int[] T = new int[M];
for (int i = 0; i < N; i++) S[i] = cS[i] == '1' ? 1 : 0;
for (int i = 0; i < M; i++) T[i] = cT[i] == '1' ? 1 : 0;
int K = sc.nextInt();
for (int i = 0; i < K; i++) {
int X = sc.nextInt();
int Y = sc.nextInt();
if (X == 1) {
System.out.println(T[Y-1]);
continue;
}
if (Y == 1) {
System.out.println(S[X-1]);
continue;
}
int xor = 0;
for (int x = 0; x < X-1; x++) {
int n = x + Y - 2;
int k = Y - 2;
if ((n & k) == k) xor ^= S[X-1-x];
}
for (int y = 0; y < Y-1; y++) {
int n = y + X - 2;
int k = X - 2;
if ((n & k) == k) xor ^= T[Y-1-y];
}
System.out.println(xor);
}
}
}
Python
N, M = list(map(int, input().split()))
S = list(map(int, list(input())))
T = list(map(int, list(input())))
K = int(input())
for _ in range(K):
X, Y = list(map(int, input().split()))
if X == 1:
print(T[Y-1])
continue
if Y == 1:
print(S[X-1])
continue
xor = 0
for x in range(X-1):
n = x+Y-2
k = Y-2
if n&k == k:
xor ^= S[X-1-x]
for y in range(Y-1):
n = y+X-2
k = X-2
if n&k == k:
xor ^= T[Y-1-y]
print(xor)
かつおぶし(難易度6)二歩
Katsuobushi(Level6)/ Two Pawns
C++
#include<bits/stdc++.h>
#define mod 998244353
using namespace std;
vector<long long> subsetConv(int n,vector<long long> &a,vector<long long> &b){
vector<long long> c(1<<n,0);
for(int i=0;i<(1<<n);i++){
for(int j=i;j<(1<<n); ++j |= i){
c[j]+=a[i]*b[i^j];
c[j]%=mod;
}
}
return c;
}
int main(){
int n;
cin >> n;
vector<string> s(n);
for(auto &nx : s){cin >> nx;}
vector<long long> cnt(n+1,0);
for(int lim=0;lim<=n;lim++){
vector<long long> f(1<<n,0);
f[0]=1;
for(int i=0;i<n;i++){
int fl=0;
for(int j=0;j<n;j++){
if(s[i][j]=='.'){fl|=(1<<j);}
}
vector<long long> g(1<<n,0);
for(int j=0;j<(1<<n);j++){
if((j|fl)!=fl){continue;}
if(__builtin_popcount(j)>lim){continue;}
g[j]++;
}
f=subsetConv(n,f,g);
}
for(auto &nx : f){
cnt[lim]+=nx;
cnt[lim]%=mod;
}
}
long long res=0;
for(long long i=1;i<=n;i++){
res+=i*(mod+cnt[i]-cnt[i-1]);
res%=mod;
}
cout << res << "\n";
return 0;
}
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long MOD = 998244353;
int N = sc.nextInt();
int M = 1<<N;
long[][] dp = new long[M][N+1];
dp[0][0] = 1;
for (int n = 0; n < N; n++) {
long[][] ndp = new long[M][N+1];
char[] S = sc.next().toCharArray();
for (int i = 0; i < M; i++) {
List<Integer> lst = new ArrayList<Integer>();
for (int j = 0; j < N; j++) {
if (!((i>>j&1) == 1 || S[j] == '#')) lst.add(j);
}
for (int j = 0; j < 1<<lst.size(); j++) {
int put = 0;
int cnt = 0;
for (int k = 0; k < lst.size(); k++) {
if ((j>>k&1) == 1) {
put |= 1<<lst.get(k);
cnt += 1;
}
}
int s = i|put;
for (int k = 0; k < N+1; k++) {
ndp[s][Math.max(cnt, k)] += dp[i][k];
if (MOD <= ndp[s][Math.max(cnt, k)]) ndp[s][Math.max(cnt, k)] -= MOD;
}
}
}
dp = ndp;
}
long ans = 0;
for (int i = 0; i < M; i++) {
for (int j = 1; j < N+1; j++) {
ans += dp[i][j] * j;
ans %= MOD;
}
}
System.out.println(ans);
}
}
Python
(実行環境をPyPyにして提出する必要があります)
mod = 998244353
def subset_conv(n, a, b):
c = [0] * (1<<n)
for i in range(1<<n):
j = i
while j < 1<<n:
c[j] += a[i] * b[i^j]
c[j] %= mod
j += 1
j |= i
return c
def main():
N = int(input())
S = [input() for _ in range(N)]
cnt = [0] * (N+1)
for lim in range(N+1):
f = [0] * (1<<N)
f[0] = 1
for i in range(N):
fl = 0
for j in range(N):
if S[i][j] == '.': fl |= 1<<j
g = [0] * (1<<N)
for j in range(1<<N):
if j|fl != fl: continue
if bin(j).count("1") >lim: continue
g[j] += 1
f = subset_conv(N, f, g)
for nx in f:
cnt[lim] += nx
cnt[lim] %= mod
res = 0
for i in range(1, N+1):
res += i * (mod+cnt[i]-cnt[i-1])
res %= mod
print(res)
if __name__ == '__main__':
main()