日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AtCoder Beginner Contest 203(Sponsored by Panasonic)题解

發布時間:2023/12/3 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AtCoder Beginner Contest 203(Sponsored by Panasonic)题解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • A - Chinchirorin
  • B - AtCoder Condominium
  • C - Friends and Travel costs
  • D - Pond
  • E - White Pawn
  • F - Weed

ABC203

A - Chinchirorin

三個條件if判

#include <cstdio> int main() {int a, b, c;scanf( "%d %d %d", &a, &b, &c );if( a == b ) return ! printf( "%d\n", c );if( a == c ) return ! printf( "%d\n", b );if( b == c ) return ! printf( "%d\n", a );printf( "0\n" );return 0; }

B - AtCoder Condominium

for循環

#include <cstdio> int main() {int n, k;scanf( "%d %d", &n, &k );int ans = 0;for( int i = 1;i <= n;i ++ )for( int j = 1;j <= k;j ++ )ans += i * 100 + j;printf( "%d\n", ans );return 0; }

C - Friends and Travel costs

sort后再for掃一遍

#include <cstdio> #include <algorithm> using namespace std; #define int long long #define maxn 200005 struct node {int pos, w; }p[maxn]; int n, k;bool cmp( node x, node y ) {return x.pos < y.pos; }signed main() {scanf( "%lld %lld", &n, &k );for( int i = 1;i <= n;i ++ )scanf( "%lld %lld", &p[i].pos, &p[i].w );sort( p + 1, p + n + 1, cmp );int ans = k, pos = 0;for( int i = 1;i <= n;i ++ )if( pos + ans >= p[i].pos ) {ans -= ( p[i].pos - pos );ans += p[i].w;pos = p[i].pos;}else break;printf( "%lld\n", pos + ans );return 0; }

D - Pond

非常樸素的扣出每一個正方形暴力做,O(nmk2)O(nmk^2)O(nmk2)

就是把每個數當成可能成為的答案做

既然每個數都來一次超時,那就二分

二分中位數,用二維前綴和做

fi,j:f_{i,j}:fi,j?: k×kk\times kk×k正方形的右下角為(i,j)(i,j)(i,j),該正方形中嚴格大于中位數的個數

sumi,j:sum_{i,j}:sumi,j?:jjj列的1→i1\rightarrow i1i嚴格大于中位數的個數

中位數在第?k22?+1\lfloor\frac{k^2}{2}\rfloor+1?2k2??+1位,那么嚴格大于的個數就為?k22?\lfloor\frac{k^2}{2}\rfloor?2k2??

只需要判斷有沒有某個正方形中fi,jf_{i,j}fi,j?比要求個數小的,這說明該正方形的中位數應該更小,那么二分值往下調;否則往上調

#include <cstdio> #include <iostream> using namespace std; #define int long long #define maxn 805 int n, k, t, ans = 1e18; int a[maxn][maxn], sum[maxn][maxn], f[maxn][maxn];int c( int x ) {if( x < 0 ) return 0;else return x; }bool check( int x ) {for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ )sum[i][j] = ( a[i][j] > x ), f[i][j] = 0;for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ )sum[j][i] += sum[j - 1][i];for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ ) {f[i][j] = f[i][j - 1] - ( sum[i][c(j - k)] - sum[c(i - k)][c(j - k)] ) + ( sum[i][j] - sum[c(i - k)][j] );if( i >= k && j >= k && f[i][j] <= t ) return 1;}return 0; }signed main() {scanf( "%lld %lld", &n, &k );for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ )scanf( "%lld", &a[i][j] );t = k * k / 2;int l = 0, r = 1e9;while( l <= r ) {int mid = ( l + r ) >> 1;if( check( mid ) ) ans = mid, r = mid - 1;else l = mid + 1;}printf( "%lld\n", ans );return 0; }

E - White Pawn

如果i+1i+1i+1行一個黑格子都沒有,那么i+1i+1i+1行的狀態與iii是一樣的,nnn的級別一下子被壓成了mmm級別

每一層最多往外擴222,那么整體來說到達點數硬存下來也是可行的

Si={whitecanreach(x,y)indepthi}S_i=\bigg\{white\ can\ reach\ (x,y)\ in\ depth_i\bigg\}Si?={white?can?reach?(x,y)?in?depthi?}

  • (j?1∈Si?1?j+1∈Si?1)?j?Si?1?j∈Si(j-1∈S_{i-1}\bigcup j+1∈S_{i-1})\bigcap j? S_{i-1}\Rightarrow j∈S_i(j?1Si?1??j+1Si?1?)?j/?Si?1??jSi?

    因為寫法其實SSS是一個,如果jjj之前已經在里面了,就沒必要加了(雖然用的是自動去重set)

  • j?1?Si?1?j+1?Si?1?j∈Si?1?j?Sij-1?S_{i-1}\bigcap j+1?S_{i-1}\bigcap j∈ S_{i-1}\Rightarrow j?S_ij?1/?Si?1??j+1/?Si?1??jSi?1??j/?Si?

#include <set> #include <cstdio> #include <vector> #include <iostream> #include <algorithm> using namespace std; set < int > s; vector < int > Old, New; vector < pair < int, int > > g; int n, m;int main() {scanf( "%d %d", &n, &m );for( int i = 0, x, y;i < m;i ++ ) {scanf( "%d %d", &x, &y );g.push_back( make_pair( x, y ) );}sort( g.begin(), g.end() );s.insert( n );for( int l = 0, r;l < m;l = r ) {for( r = l;r < m && g[l].first == g[r].first;r ++ );New.clear(), Old.clear();for( int i = l;i < r;i ++ ) {int k = g[i].second;if( ( s.find( k - 1 ) != s.end() || s.find( k + 1 ) != s.end() ) && ( s.find( k ) == s.end() ) ) New.push_back( k );if( ( s.find( k - 1 ) == s.end() && s.find( k + 1 ) == s.end() ) && ( s.find( k ) != s.end() ) ) Old.push_back( k );}for( int i = 0;i < New.size();i ++ ) s.insert( New[i] );for( int i = 0;i < Old.size();i ++ ) s.erase( Old[i] );}printf( "%d\n", s.size() );return 0; }

F - Weed

由于特殊操作?H2?\lfloor\frac{H}{2}\rfloor?2H??在,不難發現,操作次數是log?N\log NlogN級別的

將雜草高度排序,直接枚舉操作次數,記fi,j:f_{i,j}:fi,j?:iii次操作到jjj雜草為止拔草的最大數目

fi?1,k+∑ak>?aj2?,k≤j1→fi,jf_{i-1,k}+\sum_{a_k>\lfloor\frac{a_j}{2}\rfloor,k\le j}1\rightarrow f_{i,j}fi?1,k?+ak?>?2aj???,kj?1fi,j?

最后滾動掉iii這一維即可

#include <cstdio> #include <iostream> #include <algorithm> using namespace std; #define maxn 200005 int f[2][maxn]; int a[maxn]; int n, k;int main() {scanf( "%d %d", &n, &k );for( int i = 1;i <= n;i ++ )scanf( "%d", &a[i] );if( n == k ) return ! printf( "0 %d\n", n );sort( a + 1, a + n + 1 );int ans = 0;for( int i = 1;i <= 31;i ++ ) {int ip = 0, maxx = 0;for( int j = 1;j <= n;j ++ ) {while( ip < n && a[ip + 1] <= a[j] / 2 )maxx = max( maxx, f[i & 1 ^ 1][++ ip] );f[i & 1][j] = maxx + j - ip;ans = max( ans, f[i & 1][j] );}if( ans >= n - k ) return ! printf( "%d %d\n", i, n - ans );}return 0; }

總結

以上是生活随笔為你收集整理的AtCoder Beginner Contest 203(Sponsored by Panasonic)题解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。