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;
}
posted @ 2023-03-05 15:38  PHarr  阅读(76)  评论(0编辑  收藏  举报