UTPC Contest 01-27-23 Div. 2 (Beginner)
A. Printing Papers
二分一下就好了
#include<bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int main(){
int n = read();
int l = 0 , r = 30 , res , mid;
while( l <= r ){
mid = ( l + r ) >> 1;
if( (1 << mid) > n ) r = mid - 1;
else l = mid + 1 , res = ( 1 << mid );
}
cout << res;
return 0;
}
赛后发现了更简单的方法就是用 lowbit即可
#include<bits/stdc++.h>
using namespace std;
#define lowbit( x ) ( x & -x )
int32_t main() {
int x;
cin >> x;
while( x != lowbit(x) ) x -= lowbit(x);
cout << x;
}
B. Watch Your Sugar!
排个序然后买最便宜的就行
#include<bits/stdc++.h>
#define int long long
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int n = read() , s = read();
vector<int>a(n);
for( auto & i : a ) i = read();
sort( a.begin(), a.end() );
int res = 0;
for( auto i : a ){
if( i > s ) break;
s -= i , res ++;
}
cout << res;
return 0;
}
C. Flush-tastic Throwing Challenge
计算距离,为了规避浮点数运算可以比较距离的平方
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int n = read() , cx = read(), cy = read(), r = read();
r = r*r;
int ans = 0;
for( int x , y ; n ; n -- ){
x = read() , y = read();
if( ( x - cx ) * (x-cx) + (y-cy)*(y-cy) <= r ) ans ++;
}
cout << ans;
return 0;
}
D. Speedy Stamping
\(f[i]\)表示前\(i\)位的方案数,如果第\(i\)是\(T\)则\(f[i]=f[i-1]\),否则\(f[i]=f[i-1]+f[i-2]\),并且\(f[0]=f[1]=1\)
然后递推出答案就行
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e9+7;
int32_t main() {
string s; cin >> s;
int n = s.size();
vector<int> f(n+1);
f[0] = f[1] = 1;
for( int i = 2 ; i <= n ; i ++ ){
if( s[i-1] == 'T' ) f[i] = f[i-1];
else f[i] = ( f[i-1] + f[i-2] ) % mod;
}
cout << f[n];
}
E. Brainless Brainstorming
诈骗题,\(a_i=\max(a_i,b_i,c_i)\)然后只用\(a_i\)就行
\(f[i]\)表示前\(i\)位取得的最大权值,\(f[i]=\max(f[i-1],f[i-2]+a[i])\)
#include<bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int n = read() , res = 0 ;
vector<int> a(n+1 , 0 ) , f(n+1 , 0 );
for( int i = 1 ; i <= n ; i ++ ) a[i] = max( a[i] , read() );
for( int i = 1 ; i <= n ; i ++ ) a[i] = max( a[i] , read() );
for( int i = 1 ; i <= n ; i ++ ) a[i] = max( a[i] , read() );
f[1] = a[1];
for( int i = 2 ; i <= n ; i ++ )
f[i] = max( f[i-1] , f[i-2] + a[i] ) , res = max( res , f[i] );
cout << res;
return 0;
}
F. Toilet Orders
算最大公约数,然后质因数分解
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
void solve(){
int a = read() , b = read() , d = gcd( a , b );
if( d == 1 ) return printf("0\n") , void();
for( int i = 2 , cnt ; i * i <= d ; i ++ ){
if( d % i ) continue;
cnt = 0;
while( d % i == 0 ) d /= i , cnt ++;
printf("%lld %lld\n" , i , cnt );
}
if( d > 1 ) printf("%lld 1\n" , d );
printf("0\n");
return;
}
int32_t main(){
for( int t = read() ; t ; t -- ) solve();
return 0;
}
G. Crappy Typing
注意序列的顺序是不能改变的
二分答案,然后\(O(n\log n)\)判断即可
判断方法如下,开一个小根堆,放入\(m\)个\(0\),然后每次取出最小值加上当前人的用时然后重新返回队列中,重复过程,如果中间出现用时大于\(D\)的情况则不成立
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main(){
int n = read() , d = read();
vector<int> t(n);
for( int & i : t ) i = read();
auto check = [=]( int x ){
priority_queue<int,vector<int>,greater<int> > q;
for( int i = 1 ; i <= x ; i ++ ) q.push(0);
for( auto i : t ){
int s = q.top(); q.pop();
s += i ;
if( s > d ) return false;
q.push(s);
}
int ans = 0;
while( !q.empty() ) ans = q.top() , q.pop();
return ans <= d;
};
int l = 1 , r = n , res , mid;
while( l <= r ){
mid = ( l + r ) >> 1;
if( check(mid) ) res = mid , r = mid - 1;
else l = mid + 1;
}
cout << res;
return 0;
}
H. Crapper's Collapse Catastrophe
首先预处理出每一层的第一个点、最后一个点和长度。然后从最上层开始,模拟让\(x,y\)向下走直到相遇
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct Floor{
int l, r, len;
Floor( int l, int r, int len )
: l(l), r(r), len(len){}
};
int32_t main(){
int a, b, x, y;
cin >> a >> b >> x >> y;
if( x > y ) swap( x , y );
// int level = 0;
vector<Floor> building;
building.emplace_back( 0, 0, 1 );
for( int l , r , len , n = a , level = 1 ; building.back().r < y ; ){
l = building.back().r + 1 , len = building.back().len * n , r = l + len - 1;
building.emplace_back( l, r, len );
n = ( n == a ? b : a );
}
for( int i = building.size()-1 , t , p , n = ( i%2 ? a : b ); i >= 0 ; i -- ){
if( x == y ) break;
if( x >= building[i].l && x <= building[i].r )
t = x - building[i].l + 1, p = ( t + n - 1 ) / n, x = building[i-1].l + p - 1;
if( y >= building[i].l && y <= building[i].r )
t = y - building[i].l + 1, p = ( t + n - 1 ) / n, y = building[i-1].l + p - 1;
n = ( n == a ? b : a );
}
cout << x << "\n";
return 0;
}