[AtCoder Beginner Contest 215] A-G题解
文章目錄
- A - Your First Judge
- B - log2(N)
- C - One More aab aba baa
- D - Coprime 2
- E - Chain Contestant
- F - Dist Max 2
- G - Colorful Candies 2
atcoder題目鏈接
A - Your First Judge
簽到題
#include <cstdio> #include <iostream> using namespace std; string s; int main() {cin >> s;if( s == "Hello,World!" ) printf( "AC\n" );else printf("WA\n" );return 0; }B - log2(N)
簽到題
#include <cstdio> int main() {long long n;scanf( "%lld", &n );int ans;for( int i = 0;;i ++ ) {if( ( 1ll << i ) <= n ) ans = i;else break;}printf( "%d", ans );return 0; }C - One More aab aba baa
離散化后壓成整數搜索,簡單題
#include <stack> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; stack < char > sta; char s[10], rnk[10]; int t[40325], used[30]; bool vis[10]; int n, k, cnt, tot;void dfs( int x, int val ) {if( x > n ) {t[++ cnt] = val;return;}for( int i = 1;i <= n;i ++ )if( vis[i] ) continue;else {vis[i] = 1;dfs( x + 1, val * 10 + used[s[i] - 'a' + 1] );vis[i] = 0;} }int main() {scanf( "%s %d", s + 1, &k );n = strlen( s + 1 );for( char i = 'a';i <= 'z';i ++ )for( int j = 1;j <= n;j ++ )if( s[j] == i ) {used[i - 'a' + 1] = ++ tot, rnk[tot] = i;break;}dfs( 1, 0 );sort( t + 1, t + cnt + 1 );cnt = unique( t + 1, t + cnt + 1 ) - t - 1;while( t[k] ) sta.push( rnk[t[k] % 10] ), t[k] /= 10;while( ! sta.empty() ) printf( "%c", sta.top() ), sta.pop();return 0; }D - Coprime 2
質因數分解后,把質因數的倍數都篩掉,簡單題
#include <cstdio> #include <vector> #include <algorithm> using namespace std; #define maxn 100005 vector < int > ans; int cnt; bool vis[maxn], is[maxn]; int prime[maxn];void init( int n ) {for( int i = 2;i <= n;i ++ ) {if( ! vis[i] ) is[i] = 1, prime[++ cnt] = i;for( int j = 1;j <= cnt && i * prime[j] <= n;j ++ ) {vis[i * prime[j]] = 1;if( i % prime[j] == 0 ) break;}} }int n, m; int a[maxn], p[maxn * 100];int main() {init( 1e5 );scanf( "%d %d", &n, &m );for( int i = 1;i <= n;i ++ )scanf( "%d", &a[i] );cnt = 0;for( int i = 1;i <= n;i ++ ) {for( int j = 1;j * j <= a[i];j ++ )if( a[i] % j == 0 ) {if( is[j] ) p[++ cnt] = j;if( is[a[i] / j] ) p[++ cnt] = a[i] / j;}}for( int i = 1;i <= m;i ++ ) vis[i] = 0;sort( p + 1, p + cnt + 1 );cnt = unique( p + 1, p + cnt + 1 ) - p - 1;for( int i = 1;i <= cnt;i ++ )for( int j = p[i];j <= m;j += p[i] )vis[j] = 1;for( int i = 1;i <= m;i ++ )if( ! vis[i] ) ans.push_back( i );printf( "%d\n", ans.size() );for( int i = 0;i < ans.size();i ++ )printf( "%d\n", ans[i] );return 0; }E - Chain Contestant
只有101010種,符合狀壓
dpi,s,j:dp_{i,s,j}:dpi,s,j?: 到iii為止出現字符的狀態為sss,上一次出現的字符為jjj(多加一種字符表示空)
-
不選iii
dpi,s,j+=dp[i?1][s][j]dp_{i,s,j}+=dp[i-1][s][j]dpi,s,j?+=dp[i?1][s][j]
-
選iii,必須滿足iii位置字符沒出現過或上一次出現字符就是iii位置字符
dp[i][1<<t[i]∣s][t[i]]+=dp[i][1<<t[i]∣s][t[i]]+dp[i?1][s][j]dp[i][1 << t[i] | s][t[i]]+=dp[i][1 << t[i] | s][t[i]] + dp[i - 1][s][j]dp[i][1<<t[i]∣s][t[i]]+=dp[i][1<<t[i]∣s][t[i]]+dp[i?1][s][j]
簡單題
#include <cstdio> #define int long long #define mod 998244353 #define maxn 1002 #define S 1 << 10 int n; char s[maxn]; int t[maxn]; int dp[maxn][S][11];signed main() {scanf( "%lld %s", &n, s + 1 );for( int i = 1;i <= n;i ++ ) t[i] = s[i] - 'A';dp[0][0][10] = 1;for( int i = 1;i <= n;i ++ )for( int sta = 0;sta < S;sta ++ )for( int j = 0;j <= 10;j ++ )if( ! dp[i - 1][sta][j] ) continue;else {dp[i][sta][j] = ( dp[i][sta][j] + dp[i - 1][sta][j] ) % mod;if( j == 10 ) dp[i][1 << t[i] | sta][t[i]] = ( dp[i][1 << t[i] | sta][t[i]] + dp[i - 1][sta][j] ) % mod;else if( ( 1 << t[i] & sta ) and j != t[i] ) continue;elsedp[i][1 << t[i] | sta][t[i]] = ( dp[i][1 << t[i] | sta][t[i]] + dp[i - 1][sta][j] ) % mod;}int ans = 0;for( int i = 0;i < S;i ++ )for( int j = 0;j <= 10;j ++ )if( i == 0 && j == 10 ) continue;else ans = ( ans + dp[n][i][j] ) % mod;printf( "%lld\n", ans );return 0; }F - Dist Max 2
二分答案
將點按xxx坐標排序
類似滑動窗口模擬
記錄在滿足xxx坐標情況下的最大最小yyy,判斷是否有滿足與現在枚舉iii的yyy距離不小于二分答案
簡單題
#include <queue> #include <cstdio> #include <algorithm> using namespace std; #define maxn 200005 struct node { int x, y; }p[maxn]; queue < node > q; int n;int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ ) scanf( "%d %d", &p[i].x, &p[i].y );sort( p + 1, p + n + 1, []( node s, node t ) { return s.x < t.x; } );int l = 0, r = 1e9, ans;next :while( l <= r ) {int mid = l + r >> 1;while( ! q.empty() ) q.pop();int Min = 1e9, Max = 0;for( int i = 1;i <= n;i ++ ) {while( ! q.empty() ) {if( q.front().x > p[i].x - mid ) break;Min = min( Min, q.front().y );Max = max( Max, q.front().y );q.pop();}if( Min <= p[i].y - mid or Max >= p[i].y + mid ) {ans = mid, l = mid + 1;goto next;}q.push( p[i] );}r = mid - 1;}printf( "%d\n", ans );return 0; }G - Colorful Candies 2
中檔題
令CCC表示不同的糖果顏色數,將NNN顆糖果重新離散化顏色1,2,...,C
顯然答案與具體糖果的顏色無關,只與每種顏色的個數有關,令nin_ini?表示顏色為iii的糖果個數
枚舉每一輪要選擇的糖果個數KKK
對于每一種顏色,定義XiX_iXi?,若選擇糖果種有iii顏色,Xi=1X_i=1Xi?=1,否則Xi=0X_i=0Xi?=0
則KKK糖果中不同顏色種數可以表示為∑i=1CXi\sum_{i=1}^CX_i∑i=1C?Xi?
所求期望為E[∑i=1CXi]E\Big[\sum_{i=1}^CX_i\Big]E[∑i=1C?Xi?],根據期望的線性可加性知道=∑i=1CE[Xi]=\sum_{i=1}^CE\Big[X_i\Big]=∑i=1C?E[Xi?]
一個顏色出現的期望很簡單,出現的方案數///總方案數,出現的方案數===總方案數?-?一次都沒出現
E[Xi]=(NK)?(N?niK)(NK)E\Big[X_i\Big]=\frac{\binom{N}{K}-\binom{N-n_i}{K}}{\binom{N}{K}} E[Xi?]=(KN?)(KN?)?(KN?ni??)?
枚舉iii又是O(n)O(n)O(n)的時間,再加上外層的KKK枚舉,時間O(n2)O(n^2)O(n2)難以接受
發現其實如果有xxx種顏色的個數都是nin_ini?,那么這xxx種顏色的期望可以O(1)O(1)O(1)計算
x?(NK)?(N?niK)(NK)x*\frac{\binom{N}{K}-\binom{N-n_i}{K}}{\binom{N}{K}} x?(KN?)(KN?)?(KN?ni??)?
那么不同個數就是ni=1,2,...,n_i=1,2,...,ni?=1,2,...,,又要滿足∑ni=N\sum n_i=N∑ni?=N,所以可以知道上界就是根號級別ni=1,2,...,Nn_i=1,2,...,\sqrt Nni?=1,2,...,N?
后言:HHH就是FWTFWTFWT,atcoder-abc很喜歡在最后考些鵝心算法模板,不想補了
總結
以上是生活随笔為你收集整理的[AtCoder Beginner Contest 215] A-G题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cs里的CDKEY是什么
- 下一篇: [AtCoder Regular Con