gym102536部分簡要題解

敲程式碼的歐文發表於2020-12-05

A. The Slowden Files

dp[i][j][k]=1表示通過k次操作,s1的前i個字元和s2的前i+j-3個字元成功匹配。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n , m ;
char s1[maxn] , s2[maxn] ;
int ans ;
bool dp[maxn][7][4] ;
string res[] = {"You're logged in!" , "You almost got it. You're wrong in just one spot." , 
"You almost got it, but you're wrong in two spots." , 
"You're wrong in three spots." , "What you entered is too different from the real password." } ;
void solve()
{
    rep(i , 0 , n)  rep(j , 0 , 6)  rep(k , 0 , 3)  dp[i][j][k] = 0 ;
    dp[0][3][0] = 1 ;
    rep(i , 0 , n)  rep(j , 0 , 6)  rep(k , 0 , 3)
    {
        if(!dp[i][j][k])  continue ;
        int t = i + (j - 3) ;
        if(t < 0 || t > m)  continue ;
        if(k < 3)
        {
            if(j + 1 <= 6)  dp[i][j + 1][k + 1] = 1 ; //add
            if(j - 1 >= 0)  dp[i + 1][j - 1][k + 1] = 1 ; //del
        }
        if(t + 1 <= m)
        {
            if(s1[i + 1] == s2[t + 1])  dp[i + 1][j][k] = 1 ;
            else if(k + 1 <= 3) dp[i + 1][j][k + 1] = 1 ; //replace
        }  
    }
    rep(j , 0 , 6)  rep(k , 0 , 3)  if(dp[n][j][k] && n + (j - 3) == m)  ans = min(ans , k) ;
}
int main()
{
    ios ;
    int T ;
    cin >> T ;
    while(T --)
    {
        cin >> s1 + 1 >> s2 + 1 ;
        n = strlen(s1 + 1) ;
        m = strlen(s2 + 1) ;
        ans = 4 ;
        if(abs(n - m) <= 3)  solve() ;
        cout << res[ans] << '\n' ;
    }
    return 0 ;
}

B. C.U.P.S.

特判掉m=1和m=n的情況。如果m是偶數且0的個數是奇數,那麼就無解。否則可以通過連續兩次操作選m-1個相同的字元,另外這兩次操作剩餘的1個字元都選0,這樣就消除了2個0。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n , m ;
char s[maxn] ;
void solve()
{
    cin >> n >> m ;
    cin >> s + 1 ;
    int num = 0 ;
    rep(i , 1 , n)  num += (s[i] == '0') ;
    if(m == 1)
    {
        vector<int> ans ;
        rep(i , 1 , n)  if(s[i] == '0')  ans.pb(i) ;
        cout << sz(ans) << '\n' ;
        for(auto u : ans)  
        {
            rep(i , 1 , n)  cout << (i == u) ;
            cout << '\n' ;
        }
    }
    else if(m == n)
    {
        int cnt = 0 ;
        rep(i , 1 , n)  cnt += (s[i] == '1') ;
        if(cnt == n)  cout << "0\n" ;
        else if(cnt == 0)
        {
            cout << "1\n" ;
            rep(i , 1 , n)  cout << 1 ;
            cout << '\n' ;
        }
        else  cout << "CATACLYSM IMMINENT - TIME TO HOARD FACE MASKS\n" ;
    }
    else if(num % 2 == 0)//0的個數是偶數2*t,那我花費2*t天即可
    {
        vector<int> v ;
        rep(i , 1 , n)  if(s[i] == '0')  v.pb(i) ;
        cout << num << '\n' ;
        for(int i = 0 ; i < num ; i += 2)
        {
            int x = v[i] , y = v[i + 1] ;
            int cnt = 0 ;
            vector<int> t1(n + 1) , t2(n + 1) ;
            rep(i , 1 , n)  if(i != x && i != y && cnt < m - 1)  t1[i] = t2[i] = 1 , cnt ++ ;
            t1[x] = t2[y] = 1 ;
            rep(i , 1 , n)  cout << t1[i] ;
            cout << '\n' ;
            rep(i , 1 , n)  cout << t2[i] ;
            cout << '\n' ;
        }
    }
    else //0的個數是奇數2*t+1,那我花費2*t+1天即可
    {
        if(m % 2 == 0)  cout << "CATACLYSM IMMINENT - TIME TO HOARD FACE MASKS\n" ;
        else
        {
            vector<int> tmp ;
            rep(i , 1 , n)  
              if(s[i] == '0')
              {
                int cnt = 0 ;
                vector<int> t(n + 1) ;
                rep(j , 1 , n)  if(j != i && cnt < m - 1)  t[j] = 1 , s[j] = '0' + (1 - (s[j] - '0')) , cnt ++ ;
                t[i] = 1 ;
                s[i] = '1' ;
                rep(i , 1 , n)  tmp.pb(t[i]) ;
                break ;
              }
            num = 0 ;
            rep(i , 1 , n)  num += (s[i] == '0') ;
            cout << num + 1 << '\n' ;
            for(auto x : tmp)  cout << x ;
            cout << '\n' ;
            vector<int> v ;
            rep(i , 1 , n)  if(s[i] == '0')  v.pb(i) ;
            for(int i = 0 ; i < num ; i += 2)
            {
                int x , y ;
                int cnt = 0 ;
                if(i >= sz(v))  x = y = n ;
                else  x = v[i] , y = v[i + 1] ;
                vector<int> t1(n + 1) , t2(n + 1) ;
                rep(j , 1 , n)  if(j != x && j != y && cnt < m - 1)  t1[j] = t2[j] = 1 , cnt ++ ;
                t1[x] = t2[y] = 1 ;
                rep(j , 1 , n)  cout << t1[j] ;
                cout << '\n' ;
                rep(j , 1 , n)  cout << t2[j] ;
                cout << '\n' ;
            }
        }
    }
}
int main()
{
    ios ;
    int T ;
    cin >> T ;
    while(T --)  solve() ;
    return 0 ;
}

C. Senpai

\sum_{i=1}^{q}S_{i}(t)是一次函式。\sum_{i=1}^{q}P_i(t)\cdot W_i認為是模長g的向量和模長是\left \| W \right \|的向量的點積。最大化點積等價於最小化答案。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef long double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
db w , f , c ;
db sum , k , b ;
int main()
{
    ios ;
    int T ;
    cin >> T ;
    while(T --)
    {
        int q , g ;
        cin >> q >> g ;
        sum = 0 , k = 0 , b = 0 ;
        rep(i , 1 , q)  cin >> w , sum += w * w ;
        sum = sqrtl(sum) ;
        rep(i , 1 , q)  cin >> f >> c , k += f , b += c ;
        if(b < 0 || fabsl(b) < eps)
        {
            cout << "0\n" ;
            continue ;
        }
        db ans = max(b / (g * sum - k) , (db)0.0) ;
        cout << fixed << setprecision(12) << ans << '\n' ;
    }
    return 0 ;
}

D. Move to Remove Confidential Blunders

簽到。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int x ;
string s ;
int main()
{
    ios ;
    cin >> x >> s ;
    //while(getchar() != '\n') ;
    if(s == "G")
    {
        cout << "OK\n" ;
    }
    else if(s == "PG")
    {
        if(x < 13)  cout << "OK IF ACCOMPANIED\n" ;
        else  cout << "OK\n" ;
    }
    else if(s == "R-13")
    {
        if(x < 13)  cout << "ACCESS DENIED\n" ;
        else  cout << "OK\n" ;
    }
    else if(s == "R-16")
    {
        if(x < 16)  cout << "ACCESS DENIED\n" ;
        else  cout << "OK\n" ;
    }
    else
    {
        if(x < 18)  cout << "ACCESS DENIED\n" ;
        else  cout << "OK\n" ;
    }
    return 0 ;
}

E. A Floor of Many Doors

對於每種step開一個queue,然後bfs。

注意:每次只能開啟和關閉相鄰格子的門,不能開啟和關閉當前格子的門。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef long double db ;
const int mod = 998244353 ;
const int maxn = 5000 + 10 ;
const int maxm = 2e4 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int r , c , k ;
int S , T ;
char s[maxn][maxn] ;
int row[4] = {-1 , 1 , 0 , 0} ;
int col[4] = {0 , 0 , -1 , 1} ;
queue<pii> q[maxm] ;
int d[maxm][55] ;
int c1(int x , int y)
{
    return x * c + y ;
}
void update(int now , int door , int step)
{
    if(d[now][door] > step)
    {
        d[now][door] = step ;
        q[step].push({now , door}) ;
    }
}
int main()
{
    ios ;
    int cas ;
    cin >> cas ;
    while(cas --)
    {
        cin >> r >> c >> k ;
        rep(i , 0 , r - 1)  cin >> s[i] ;
        rep(i , 0 , r - 1)  rep(j , 0 , c - 1)  
        {
            if(s[i][j] == 'A')  S = c1(i , j) ;
            if(s[i][j] == 'B')  T = c1(i , j) ;
        }
        rep(i , 0 , 3 * r * c)  while(!q[i].empty())  q[i].pop() ;
        rep(i , 0 , r * c)  rep(j , 0 , k)  d[i][j] = inf ;
        q[0].push({S , 0}) ;
        rep(step , 0 , 3 * r * c)
        {
            while(!q[step].empty())
            {
                pii u = q[step].front() ;
                q[step].pop() ;
                if(u.fi == T)
                {
                    cout << step << '\n' ;
                    goto ff ;
                }
                //ddebug(u.fi , u.se) ;
                int x = u.fi / c ;
                int y = u.fi % c ;
                int door = u.se ;
                for(int i = 0 ; i <= 3 ; i ++)
                {
                    int nx = x + row[i] ;
                    int ny = y + col[i] ;
                    int nxt = c1(nx , ny) ;
                    if(nx < 0 || nx >= r || ny < 0 || ny >= c)  continue ;
                    if(s[nx][ny] == '#')  continue ;
                    if(s[nx][ny] == 'D')
                    {
                        if(s[x][y] == 'D')
                        {
                            if(door < k)  
                            {
                                //關當前門
                                update(nxt , door , step + 3) ;
                                //不關當前門
                                update(nxt , door + 1 , step + 2) ;
                            }
                        }
                        else
                        {
                            if(door < k)  update(nxt , door + 1 , step + 2) ;
                        }
                    }
                    else
                    {
                        if(s[x][y] == 'D')
                        {
                            //關當前門
                            update(nxt , door - 1 , step + 2) ;
                            //不關當前門
                            update(nxt , door , step + 1) ;
                        }
                        else
                        {
                            update(nxt , door , step + 1) ;
                        }
                    }
                }
            }
        }
        cout << "HAHAHUHU\n" ;
        ff: ;
    }
    return 0 ;
}

I. Glory to Algotzka

dp[i][j].fi表示以i為根的子樹的大小是j的連通塊的最小的S個數。dp[i][j].se表示以i為根的子樹的大小是j的連通塊的最大的S個數。這段區間是連續的。

直接跑揹包就好了。複雜度是n^2。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 1e4 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n , q ;
vector<int> g[maxn] ;
pii dp[maxn][maxn] ;
char s[maxn] ;
int siz[maxn] ;
void dfs(int u)
{
    siz[u] = 1 ;
    rep(i , 1 , n)  dp[u][i].fi = inf , dp[u][i].se = -1 ;
    dp[u][1].fi = dp[u][1].se = (s[u] == 'S') ;
    for(auto v : g[u])
    {
        dfs(v) ;
        per(i , siz[u] , 1)  rep(j , 1 , siz[v])
        {
            dp[u][i + j].fi = min(dp[u][i + j].fi , dp[u][i].fi + dp[v][j].fi) ;
            dp[u][i + j].se = max(dp[u][i + j].se , dp[u][i].se + dp[v][j].se) ;
        }
        siz[u] += siz[v] ;
    }
}
int main()
{
    ios ;
    cin >> n >> q ;
    rep(i , 1 , n)
    {
        int x ;
        cin >> x ;
        g[x].pb(i) ;
    }
    cin >> s + 1 ;
    dfs(1) ;
    while(q --)
    {
        int i , c , s ;
        cin >> i >> c >> s ;
        if(c + s <= siz[i] && dp[i][c + s].fi <= s && s <= dp[i][c + s].se)  cout << "COMPROMISED\n" ;
        else  cout << "NOT COMPROMISED\n" ;
    }
    return 0 ;
}

K. I Brook the Code!

簽到。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n ;
struct node
{
    ll w , h ;
    bool operator < (const node &s) const
    {
        return h < s.h ;
    }
} a[maxn] ;
int main()
{
    ios ;
    cin >> n ;
    rep(i , 1 , n)  cin >> a[i].w ;
    rep(i , 1 , n)  cin >> a[i].h ;
    sort(a + 1 , a + n + 1) ;
    rep(i , 1 , n)  cout << a[i].w << " \n"[i == n] ;
    return 0 ;
}

L. Break the Pattern!

f(x)=(x-s_1)(x-s_2)\cdots (x-s_l)

兩個相同的s_i,s_j,認為是一個s_i

輸出f(x),2f(x),3f(x),\cdots ,nf(x)即可。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 999983 ;
const int maxn = 100 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
ll dp[maxn][maxn] ;
int main()
{
    ios ;
    int T ;
    cin >> T ;
    while(T --)
    {
        int n , k , l ;
        cin >> n >> k >> l ;
        set<int> s ;
        rep(i , 0 , k)  rep(j , 0 , k)  dp[i][j] = 0 ;
        dp[0][0] = 1 ;
        int cnt = 0 ;
        rep(i , 1 , l)
        {
            int x ;
            cin >> x ;
            if(s.count(x))  continue ;
            cnt ++ ;
            s.insert(x) ; 
            rep(j , 1 , cnt)  dp[cnt][j] = dp[cnt - 1][j - 1] ;
            rep(j , 0 , cnt)  dp[cnt][j] += dp[cnt - 1][j] * (mod - x) % mod ;
            //rep(j , 0 , cnt)  cout << dp[cnt][j] << " \n"[j == cnt] ;
        }
        if(k < cnt)  cout << "0\n" ;
        else
        {
            cout << n << '\n' ;
            rep(i , 1 , n)  
            {
                cout << cnt << ' ' ;
                per(j , cnt , 0)  cout << dp[cnt][j] * i % mod << " \n"[j == 0] ;
            }
            
        }
    }
    return 0 ;
}

 

相關文章