第一届 acc 题解

1|0初赛


1|1数圈圈


转化成 16 进制统计一下

#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 23; int n , m ; inline int read() { int x = 0 , ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar(); return x ; } int main(){ int t , n = read() , cnt = 0; while( n ) { t = n % 16 , n /= 16; if( t == 0 || t == 4 || t == 6 || t == 9 || t == 10 || t == 13 ) cnt ++; else if( t == 8 || t == 11 ) cnt += 2; } cout << cnt << endl; return 0; }

1|2农田灌溉


找到最大的差即可

#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 205; int n , k , a[N] , len = 0; inline int read() { int x = 0 , ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar(); return x ; } void slove() { n = read() , k = read() , a[1] = read() , len = 0; for( int i = 2 ; i <= k ; i ++ ) a[i] = read() , len = max( len , a[i] - a[i-1] + 1 ); len = len / 2 + ( len & 1 ); len = max( len , a[1]); len = max( len , n - a[k] + 1 ); printf("%d\n" , len ); } int main(){ int t = read(); while(t --) slove(); return 0; }

1|3选取数对


就是搜索就好了,但是需要加一些可行性剪枝

#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 205; int n , m , k; ll a[N] , res; inline int read() { int x = 0 , ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar(); return x ; } void dfs( int x , int t , ll sum ) { if( t > k ) { res = max( res , sum ); return ; } if( x > n ) return ; for( int i = x ; i <= n ; i ++ ) { if( i + (k - t + 1 ) * m - 1 > n ) return ;// 剪枝 dfs( i + m , t+1 , sum + a[i+m-1] - a[i-1] ); } } int main(){ n = read() , m = read() , k = read(); for( int i = 1 ; i <= n ; i ++ ) a[i] = read(); for( int i = 1 ; i <= n ; i ++ ) a[i] += a[i-1]; dfs( 1 , 1 , 0 ); cout << res << endl; return 0; }

2|0决赛


2|1两个闹钟


有计算的方法,但是暴力的枚举然后设一个较大的上届就好了

#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e6+5; int a , b , c , d; int read() { int x = 0 , ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1)+ch-'0',ch=getchar(); return x; } int main() { a = read() , b = read() , c = read() , d = read(); while( b != d && b < 1e8 ) { while( b < d ) b += a; while( d < b ) d += c; } if( b == d ) cout << b << endl; else cout << -1 << endl; return 0; }

2|2合并石子


贪心的选择最小的合成方法就好了

如果对于[l,r]相等,如果存在[l,k]相等则[k+1,r]也一定相等,这样操作就可以使区间数加一,不断操作直到不能操作就是答案

#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e6+5; int n , m , a[N] , b[N] , k; int read() { int x = 0 , ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( ch >= '0' && ch <= '9' ) x = (x<<3)+(x<<1)+ch-'0',ch=getchar(); return x; } int main() { n = read() , m = read(); for( int i = 1 ; i <= n ; i ++ ) a[i] = read(); for( int i = 1 ; i <= m ; i ++ ) b[i] = read(); int i = 1 , j = 1 , suma , sumb; while( i <= n && j <= m ) { k ++ , suma = a[i] , sumb = b[j] , i ++ , j ++; while( suma != sumb ) { while( suma < sumb ) suma += a[i++]; while( sumb < suma ) sumb += b[j++]; } } cout << k << endl; return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/16132006.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示