Codeforces Round #725 (Div. 3) 题解
文章目錄
- A. Stone Game
- B. Friends and Candies
- C. Number of Pairs
- D. Another Problem About Dividing Numbers
- E. Funny Substrings
- F. Interesting Function
- G. Gift Set
#725-Div.3
A. Stone Game
先找到最大值最小值的位置,然后有三種選取(兩邊中走一邊/兩邊都走一點)
#include <cstdio> #include <cstring> #include <iostream> using namespace std; #define maxn 105 int T, n; int a[maxn]; bool vis[maxn];int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%d", &a[i] );int minn = maxn, maxx = -maxn, pos_min, pos_max;for( int i = 1;i <= n;i ++ ) {if( a[i] < minn ) minn = a[i], pos_min = i; if( a[i] > maxx ) maxx = a[i], pos_max = i;}int l = min( pos_min, pos_max ), r = max( pos_min, pos_max );printf( "%d\n", min( r, min( n - l + 1, l + n - r + 1 ) ) );}return 0; }B. Friends and Candies
首先糖果要能被均分,然后肯定是糖果多的人分給別人
#include <cstdio> #define maxn 200005 int T, n; int a[maxn];int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d", &n );int tot = 0;for( int i = 1;i <= n;i ++ ) {scanf( "%d", &a[i] );tot += a[i];}if( tot % n ) printf( "-1\n" );else {tot /= n;int ans = 0;for( int i = 1;i <= n;i ++ )if( a[i] > tot ) ans ++;printf( "%d\n", ans );}}return 0; }C. Number of Pairs
先排個序,用lower_bound/upper_bound查詢要求值域中的值
#include <cstdio> #include <algorithm> using namespace std; #define maxn 200005 #define int long long int T, n, l, r; int a[maxn];signed main() {scanf( "%lld", &T );while( T -- ) {scanf( "%lld %lld %lld", &n, &l, &r );int ans = 0;for( int i = 1;i <= n;i ++ )scanf( "%lld", &a[i] );sort( a + 1, a + n + 1 );for( int i = 1;i < n;i ++ ) {if( a[i] > r ) continue;int L, R;R = upper_bound( a + i + 1, a + n + 1, r - a[i] ) - a - 1 - 1;L = lower_bound( a + i + 1, a + n + 1, l - a[i] ) - a - 1 - 1;ans += R - L;}printf( "%lld\n", ans );}return 0; }D. Another Problem About Dividing Numbers
特判k=1的情況
最小的操作次數肯定是222,直接除成111,所以只需要考慮最大操作次數,在這之間的操作次數肯定都是可以達到的,顯然
最大操作次數就是唯一質因數分解的冪次和
剛開始還擔心根號帶TTT跑不過(#.#)
#include <cstdio> #include <cmath> #include <iostream> using namespace std; int T, a, b, k;int gcd( int x, int y ) {if( x < y ) swap( x, y );if( ! y ) return x;else return gcd( y, x % y ); }int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d %d %d", &a, &b, &k );if( k == 1 ) {if( a == b ) printf( "No\n" );else if( a % b == 0 || b % a == 0 ) printf( "Yes\n" );else printf( "No\n" );continue;}int cnta = 0, Sqr = sqrt( a );for( int i = 2;i <= Sqr;i ++ )if( a % i == 0 )while( a % i == 0 ) a /= i, cnta ++;if( a != 1 ) cnta ++;int cntb = 0; Sqr = sqrt( b );for( int i = 2;i <= Sqr;i ++ )if( b % i == 0 )while( b % i == 0 ) b /= i, cntb ++;if( b != 1 ) cntb ++;if( k <= cnta + cntb ) printf( "Yes\n" );else printf( "No\n" );}return 0; }E. Funny Substrings
過分原始的暴力模擬不可取,瘋狂自疊加字符串長度可以達到2502^{50}250級別,望而卻步
事實上對于每一個字符串,我們只需要存下haha的個數,長度,以及前后各三個字符即可
因為只有這特殊的六個字符才可能與新的字符串相加時產生新的haha
#include <map> #include <cstdio> #include <iostream> using namespace std; #define int long long struct word {int len, cnt;string s; }; map < string, word > mp;string GetHead( string s ) {if( s.size() < 3 ) return s;else return s.substr( 0, 3 ); }string GetTail( string s ) {if( s.size() < 3 ) return s;else return s.substr( s.size() - 3, 3 ); }int calc( string s, string p ) {int cnt = 0;for( int i = 0;i + p.size() <= s.size();i ++ )if( s.substr( i, p.size() ) == p ) cnt ++;return cnt; }word merge( word a, word b ) {word New;New.len = a.len + b.len;New.cnt = a.cnt + b.cnt + calc( GetTail( a.s ) + GetHead( b.s ), "haha" );New.s = a.s + b.s;if( New.s.size() > 7 ) New.s = GetHead( a.s ) + "#" + GetTail( b.s );return New; }signed main() {int T, n;string a, b, c, op, plus;scanf( "%lld", &T );while( T -- ) {mp.clear();scanf( "%lld", &n );int ans = 0;while( n -- ) {cin >> a >> op >> b;if( op == ":=" ) {word New;New.cnt = calc( b, "haha" );New.len = b.length();New.s = b;mp[a] = New;}else {cin >> plus >> c;mp[a] = merge( mp[b], mp[c] );}ans = mp[a].cnt;}printf( "%lld\n", ans );}return 0; }F. Interesting Function
差分一下
發現對于任何數位上的值,完整向前一位進111,變換次數都是101010
所以枚舉數位,看前面進位次數乘個101010,再加上該數位的值即可
#include <cstdio> #define int long long int cnt[20];int solve( int x ) {int ans = 0;while( x ) {int r = x % 10; x /= 10;ans += x * 10 + r;}return ans; }signed main() {int T, l, r;scanf( "%lld", &T );while( T -- ) {scanf( "%lld %lld", &l, &r );printf( "%lld\n", solve( r ) - solve( l ) );}return 0; }G. Gift Set
能分成nnn個組合,就蘊含n?1n-1n?1
所以考慮二分組合個數ttt,假設x>y,a>bx>y,a>bx>y,a>b
x,yx,yx,y都至少會減去t×bt\times bt×b個,剩下了t×(a?b)t\times(a-b)t×(a?b)就隨機讓x?t×b,y?t×bx-t\times b, y-t\times bx?t×b,y?t×b補上
用向下取整判斷即可
#include <cstdio> #include <iostream> using namespace std; int T, x, y, a, b;bool check( int t ) {int X = x - t * b, Y = y - t * b;if( X / ( a - b ) + Y / ( a - b ) >= t ) return 1;else return 0; }int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d %d %d %d", &x, &y, &a, &b );if( a == b ) {printf( "%d\n", min( x / a, y / b ) );continue;}if( x < y ) swap( x, y );if( a < b ) swap( a, b );int l = 0, r = y / b, ans;while( l <= r ) {int mid = ( l + r ) >> 1;if( check( mid ) ) ans = mid, l = mid + 1;else r = mid - 1;}printf( "%d\n", ans );}return 0; }總結
以上是生活随笔為你收集整理的Codeforces Round #725 (Div. 3) 题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Layui 数据表格动态cols(字段)
- 下一篇: Codeforces Round #70