【中南林业科技大学第十一届程序设计大赛】 A B C D E G H I K

A 译码

当成26进制数处理就好了

代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N = (int) 1e5 + 11;
const int M = (int) 1e5 + 11;
const int mod = (int) 1e9 + 7;
const int inf = 0x3f3f3f3f;

string Change(string s){
    int val = 0;
    for(int i = 0; s[i]; i++) val = val * 10 + s[i] - '0';
    string ans = "";
    while(val){
        ans += (val % 26 + 'a');
        val /= 26;
    }
    while(ans.size() < 3) ans += 'a';
    reverse(ans.begin(), ans.end());
    return ans;
}

int main(){
    int T;scanf("%d", &T);
    while(T--){
        int n; scanf("%d", &n);
        string s; cin>> s;
        string t = ""; string ans = "";

        for(int i = 0; s[i]; i++){
            t += s[i];
            if((i + 1) % 5 == 0){
                ans += Change(t);
                t = "";
            }
        }
        cout<< ans<<endl;
    }
return 0;
}

B Fence Repair

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N = (int) 1e5 + 11;
const int M = (int) 1e5 + 11;
const int mod = (int) 1e9 + 7;
const int inf = 0x3f3f3f3f;

int a[N];
int main(){
    int n;
    while(scanf("%d", &n) !=EOF){
        for(int i = 0; i < n; i++) scanf("%d", &a[i]);

        int ans = 0;
        for(int i = 0; i < n; i++){
            for(int j = i + 1; j < n; j++){
                if(a[i] << 1 == a[j]) ans ++;
            }
        }
        printf("%d\n", ans);
    }
return 0;
}

C 有趣的二进制

#include <bits/stdc++.h>
using namespace std;


int out(long long n){
    int ret = 0;
    for (int i = 63; i >= 0; i--) {
        if((n & (1ll << i)) != 0) ret ++;
    }
    return ret;
}

int main() {
    long long n;
    while (scanf("%lld", &n)!= EOF) {
        int ans = out(n);
        printf("%d\n", ans);
    }
    return 0;
}

D 有趣的数字

分析: 我是先打表,然后找到的规律
代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N = (int) 1e5 + 11;
const int M = (int) 1e5 + 11;
const int mod = (int) 1e9 + 7;
const int inf = 0x3f3f3f3f;


bool vis[N];
int solve(int n){
    memset(vis, false, sizeof(bool) * (n  + 1));

    for(int i = 1; i <= n; i++){
        for(int j = 1; j * i <= n; j++){
            vis[j * i] = !vis[j * i];
        }
    }

    int cnt = 0;
    for(int i = 1; i <= n; i++){
        if(!vis[i]) cnt++;
    }
    return cnt;
}

void init(int n){
    for(int i = 1; i<= n; i++){
            int t  = solve(i);
        printf("@@ %d %d %d \n", i, t, t - i);
    }
}
 /*  上面部分都是 打表找规律部分     */


ll Binary(ll n){
    ll l = 1, r = inf;
    ll ans ;
    while(l <= r){
        ll mid = (l + r) >> 1;
        //printf("@@ %d \n", mid);

        if((3 + 3 + (mid - 1) * 2 ) * mid / 2 >= n) {
            ans = mid;  r = mid - 1;
        }else l = mid + 1;
    }

    return ans;
}


int main(){
   // init(10);
    ll n;
    while(~scanf("%lld", &n)){
        printf("%lld\n", n - Binary(n));
    }
return 0;
}

E 邝博士的问题

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N = (int) 1e5 + 11;
const int M = (int) 1e5 + 11;
const int mod = (int) 1e9 + 7;
const int inf = 0x3f3f3f3f;



int main(){
    ll n;
    while(~scanf("%lld", &n)){
        ll a = (ll)floor(n * 0.1); ll aa = (ll)ceil(n * 0.1);
        ll b = (ll)floor(n * 0.2); ll bb = (ll)ceil(n * 0.2);
        ll c = (ll)floor(n * 0.3); ll cc = (ll)ceil(n * 0.3);

        printf("%lld %lld %lld\n",aa - a, aa + bb - (a + b), aa + bb + cc - (a + b + c));
    }
return 0;
}

G 组合游戏

分析: 优先队列处理一下就行
代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N = (int) 1e5 + 11;
const int M = (int) 1e5 + 11;
const int mod = (int) 1e9 + 7;
const int inf = 0x3f3f3f3f;

priority_queue<int, vector<int>, greater<int> > que;
int main(){
    int n;
    while(~scanf("%d", &n)){
        for(int i = 0; i < n; i++){
            int val; scanf("%d", &val);
            que.push(val);
        }
        int ans =0;
        while(!que.empty()) {
            int a = que.top(); que.pop();
            if(que.empty()) break;
            int b = que.top(); que.pop();
            ans += a + b;
            que.push(a + b);
        }
        printf("%d\n", ans);
    }
return 0;
}

H 渴望力量吗

分析: 莫队 裸过。
看别人代码,居然 有纯暴力可以过得。(⊙o⊙)… Emmm
代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N = (int) 300000 + 11;
const int M = (int) 1e5 + 11;
const int mod = (int) 1e9 + 7;
const int inf = 0x3f3f3f3f;


int B;
struct Ques{
    int le, ri, k, id;
    Ques(){}
    Ques(int _le, int _ri, int _k, int _id){
        le = _le; ri = _ri; k = _k; id = _id;
    }
    bool operator < (const Ques &b)const{
        if(le / B == b.le / B) return ri < b.ri;
        else return le / B < b.le / B;
    }
}Q[N]; int ANS[N];

int a[N]; map<int, int>cnt;
void Add(int id){
    cnt[a[id]] ++ ;
}
void Del(int id){
    cnt[a[id]] --;
}

void solve(int q, int n){
    cnt.clear();
    sort(Q + 1, Q + 1 + q);
    int L = 1, R = 0;
    for(int i = 1; i <= q; i++){
        while(R < Q[i].ri) Add(++R);
        while(R > Q[i].ri) Del(R--);
        while(L < Q[i].le) Del(L++);
        while(L > Q[i].le) Add(--L);
        ANS[Q[i].id] = cnt[Q[i].k];
    }
}

int main(){
    int n;
    while( scanf("%d", &n) != EOF){
        B = (int)ceil(sqrt(n * 1.0));
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        int q; scanf("%d", &q);
        for(int i = 1; i <= q; i++){
             int le, ri , k;  scanf("%d%d%d", &le, &ri, &k);
             Q[i] = Ques(le, ri, k, i);
        }
        solve(q, n);
        for(int i = 1; i <= q; i++){
            printf("%d\n", ANS[i]);
        }
    }
return 0;
}

I 背包问题

分析: 题目中给的 数组开不下,但是我们注意到 物品数目只有30个,这里用到的是折半枚举,我们先状压枚举出前一半物品的每一种情况的体积和,并储存下来排序。 然后再状压枚举另一半,然后在前一半的情况中找和当前枚举的情况的和小于总体积的个数

留意 其实30这个数据范围就很别致,有时候可以往折半枚举这个思路上靠近。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N = (int) 1e5 + 11;
const int M = (int) 1e6 + 11;
const int mod = (int) 1e9 + 7;
const int inf = 0x3f3f3f3f;


ll v[N];
vector<ll>ve;
int main(){
    ll n, m; 
    while(~scanf("%lld%lld", &n, &m)){

        for(int i = 0; i < n; i++) scanf("%lld", &v[i]);
        ve.clear(); 
        for(ll i = 0; i < (1ll << n / 2); i++){
            ll tmp = 0;
            for(ll j = 0; j < n; j++){
                if(i >> j & 1) tmp += v[j];
            }
            if(tmp <= m) ve.push_back(tmp);
        }

        sort(ve.begin(), ve.end()) ;
        ll t = n / 2;
        ll ans = 0; n -= n / 2; 
        for(ll i = 0; i < (1ll << n); i++){
            ll tmp = 0;
            for(ll j = 0; j < n; j++){
                if(i >> j & 1) tmp += v[j + t];
            }

            if(tmp <= m){
                ans += upper_bound(ve.begin(), ve.end(), m - tmp) - ve.begin();
            } 
        }

        printf("%lld\n", ans);
     }
    return 0;
 } 

K 序列求和

分析: 有公式就是好。
代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N = (int) 1e5 + 11;
const int M = (int) 1e5 + 11;
const int mod = (int) 1e9 + 7;
const int inf = 0x3f3f3f3f;

ll qpow(ll a, ll b, ll c){
    ll base = a % c, s = 1;
    while(b){
        if(b & 1) s = s * base % c;
        base = base * base % c;
        b >>= 1;
    }
    return s;
}
ll inv(ll a, ll b){
    return qpow(a, b - 2, b);
}

int main(){
    ll n;
    ll tmp = inv(6, mod);
    while(scanf("%lld", &n) != EOF){

        printf("%lld\n", n % mod * ((n % mod + 1) % mod) % mod * (2 * n % mod + 1 % mod) % mod * tmp % mod);
    }
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37383726/article/details/80766822