XMUOJ校外实训1

校外实训 \(1\) 全部更新到 \(4.x\) 题目。

第一部分

A+B

a, b = map(int, input().strip().split())
print(a + b)

熄灯问题

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

int n = 5, m = 6;
int a[10][10]; 

int vis[10]; // 枚举第一行的
int ans[10][10]; 
int fx[5] = {0, 1, -1, 0, 0}; 
int fy[5] = {0, 0, 0, 1, -1}; 

bool check(){
    memset(ans, 0, sizeof(ans)); 
    int b[10][10]; 
    memcpy(b, a, sizeof(b)); 
    for(int i = 1; i <= m; i++){
        if(vis[i]){
            for(int k = 0; k <= 4; k++){
                b[1+fx[k]][i+fy[k]] ^= 1; 
            }
        }  
        ans[1][i] = vis[i]; 
    }
    for(int i = 2; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(b[i-1][j] == 0) continue; 
            else{
                ans[i][j] = 1; 
                for(int k = 0; k <= 4; k++){
                    b[i+fx[k]][j+fy[k]] ^= 1; 
                }
            }
        }
    }
    // for(int i = 1; i <= n; i++){
    //     for(int j = 1; j <= m; j++){
    //         cout << b[i][j] << " "; 
    //     }
    //     cout << endl; 
    // }
    // cout << "---------------------\n" << endl; 
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(b[i][j] == 1) return 0; 
        }
    }
    return 1; 
}

bool flag = 0; 

void dfs(int now){
    if(flag) return ; 
    if(now == 7){
        if(check()){
            flag = 1; 
        }
        return ; 
    }
    for(int i = 0; i < 2; i++){
        vis[now] = i; 
        dfs(now + 1); 
    }
    return ; 
}

int main(){
    int T; cin >> T; 
    for(int Case = 1; Case <= T; Case++){
        flag = 0; 
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++)
                cin >> a[i][j]; 
        }
        dfs(1); 
        printf("PUZZLE #%d\n", Case); 
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                printf("%d ", ans[i][j]); 
            }
            printf("\n"); 
        }
    }
    return 0; 
}

排序考试

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

int main(){
    int T; cin >> T; 
    while(T--){
        int n; cin >> n; 
        vector <int> G; 
        for(int i = 1; i <= n; i++){
            int x; cin >> x; 
            G.push_back(x); 
        }
        sort(G.begin(), G.end()); 
        for(int i = 0; i < G.size(); i++){
            cout << G[i]; 
            if(i == G.size() - 1)
                continue; 
            cout << " "; 
        }
        cout << endl; 
    }
    return 0; 
}

完美立方

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100010

int n; 
ll Cu(ll x){
    return x * x * x; 
} 

struct node{
    int a, b, c, d; 
} t[N]; 

bool cmp(node a, node b){
    return a.a < b.a || (a.a == b.a && a.b < b.b) || (a.a == b.a && a.b == b.b && a.c < b.c) || (a.a == b.a && a.a == b.b && a.c == b.c && a.d < b.d); 
}

int main(){
    cin >> n; 
    int cnt = 0; 
    for(int a = 1; a <= n; a++){
        for(int b = a; b >= 2; b--){
            for(int c = b;c >= 2; c--){
                for(int d = c; d >= 2; d--){
                    if(Cu(a) == Cu(b) + Cu(c) + Cu(d)){
                        t[++cnt] = (node){a, d, c, b}; 
                    }
                }
            }
        }
    }
    sort(t + 1, t + cnt + 1, cmp);
    for(int i = 1; i <= cnt; i++){
        printf("Cube = %d, Triple = (%d,%d,%d)\n", t[i].a, t[i].b, t[i].c, t[i].d); 
    } 
    return 0; 
}

人的周期

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

int p, e, h, d; 

int main(){
    int Case = 0; 
    while(cin >> p >> e >> h >> d && p != -1){
        Case++; 
        while(p - 23 >= 0) p -= 23; 
        while(e - 28 >= 0) e -= 28; 
        while(h - 33 >= 0) h -= 33; 
        int now = d; 
        while(666){
            now++; 
            if((now - p) % 23 == 0 && (now - e) % 28 == 0 && (now - h) % 33 == 0){
                break; 
            }
            
        }
        printf("Case %d: the next triple peak occurs in %d days.\n", Case, now - d); 
    }
    return 0; 
}

假币问题

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


int vis[27]; 

struct Query{
    string s[3]; 
} q[3]; 

bool hav = 0; 
int check(int h, int weight){ // weight == 1: 重
    string now;
    now.push_back(h);  
    for(int i = 0; i < 3; i++){ // 对每个Query 检查
        string l = q[i].s[0], r = q[i].s[1], result = q[i].s[2]; 
        if(weight == 0) swap(l, r); 
        switch (result[0])
        {
        case 'u':
            if(l.find(now) == string::npos) return 0; 
            break; 
            break;
        case 'd':
            if(r.find(now) == string::npos) return 0; 
            break; 
        case 'e':
            if(l.find(now) != string::npos || r.find(now) != string::npos) return 0; 
            break; 
        default:
            break;
        }
    }
    return 1; 
}

int main(){
    int T; cin >> T; 
    while (T--){
        for(int i = 0; i < 3; i++){
            cin >> q[i].s[0] >> q[i].s[1] >> q[i].s[2]; 
        }
        for(int now = 'A'; now <= 'L'; now++){
            // hav = 0; 
            bool ans = check(now, 1); 
            if(ans){
                // if(!hav) continue; 
                printf("%c is the counterfeit coin and it is heavy. \n", now); 
                break; 
            }
            ans = check(now, 0); 
            if(ans){
                // if(!hav) continue; 
                printf("%c is the counterfeit coin and it is light. \n", now); 
                break; 
            }
        }
    }
    return 0; 
    
}

两数之和

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

int tot, n; 
int a[N];

int main(){
    cin >> tot >> n; 
    for(int i = 1; i <= n; i++){
        cin >> a[i]; 
    }
    int p = 1, q = n; 
    while(a[p] + a[q] != tot){
        if(a[p] + a[q] > tot) q--; 
        else if(a[p] + a[q] < tot) p++; 
    }
    cout << p - 1 << " " << q - 1 << endl; 
    return 0; 
}

三数之和

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

int n; 
int a[N]; 
int tot; 

struct node{
    int x, y, z;

    bool operator < (const node &a) const{
        if(x < a.x) return 1; 
        else if(x == a.x && y < a.y) return 1; 
        else if(x == a.x && y == a.y && z < a.z) return 1; 
        else return 0; 
    }
} ; 

int main(){
    cin >> tot >> n; 
    for(int i = 1; i <= n; i++){
        cin >> a[i]; 
    }
    sort(a + 1, a + n + 1); 
    vector <node> G; 
    for(int k = 2; k <= n - 1; k++){
        int p = 1, q = n; 
        while(p < k && q > k){
            if(a[p] + a[q] > tot - a[k]) q--; 
            if(a[p] + a[q] < tot - a[k]) p++; 
            if(a[p] + a[q] + a[k] == tot && a[p] != a[q] && a[p] != a[k] && a[q] != a[k]) 
                G.push_back((node){a[p], a[k], a[q]}), p++;
        }   
        if(p == k || q == k) continue; 
    }
    sort(G.begin(), G.end()); 
    for(auto it : G){
        cout << it.x << " " << it.y << " " << it.z << endl; 
    }
    return 0; 
}

四数之和

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

int n; 
int a[N]; 
int tot; 

struct node{
    int x, y, z, m;

    bool operator < (const node &a) const{
        if(x < a.x) return 1; 
        else if(x == a.x && y < a.y) return 1; 
        else if(x == a.x && y == a.y && z < a.z) return 1; 
        else if(x == a.x && y == a.y && z == a.z && m < a.m) return 1; 
        else return 0; 
    }
} ; 

int main(){
    cin >> tot >> n; 
    for(int i = 1; i <= n; i++){
        cin >> a[i]; 
    }
    sort(a + 1, a + n + 1); 
    vector <node> G; 
    for(int k = 2; k <= n - 1; k++){
    for(int h = k + 1; h <= n - 1; h++){
        int p = 1, q = n; 
        while(p < k && q > h){
            if(a[p] + a[q] > tot - a[k] - a[h]) q--; 
            if(a[p] + a[q] < tot - a[k] - a[h]) p++; 
            if(a[p] + a[q] + a[k] + a[h] == tot && a[p] != a[q] && a[p] != a[k] && a[q] != a[k]) 
                G.push_back((node){a[p], a[k], a[h], a[q]}), p++;
        }   
    }
    }
    sort(G.begin(), G.end()); 
    for(auto it : G){
        cout << it.x << " " << it.y << " " << it.z << " " << it.m << endl; 
    }
    return 0; 
}

二进制密码锁

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

char a[N], b[N], t[N]; 
int n; 

int minn = 1e9; 

int main(){
    scanf("%s", a + 1); 
    scanf("%s", t + 1); 
    n = strlen(a + 1); 
    for(int i = 1; i <= n; i++){
        a[i] -= '0'; 
        t[i] -= '0'; 
    }
    for(int i = 0; i <= 2; i++){
            int num = 0; 
            memcpy(b, a, sizeof(b)); 
            if(i == 1){
                b[1] ^= 1, b[2] ^= 1; 
                num++; 
            }
            
            
            for(int i = 2; i <= n; i++){
                if(b[i-1] != t[i-1]){
                    b[i-1] ^= 1, b[i] ^= 1, b[i+1] ^= 1; 
                    num++; 
                }   
            }
            bool flag = 1;  
            for(int i = 1; i <= n; i++){
                if(b[i] != t[i]) flag = 0; 
            }
            if(flag){
                minn = min(minn, num); 
            }
        
    }
    if(minn == 1e9)
        cout << "impossible " << endl; 
    else cout << minn << endl;
    return 0; 
}

第二部分

汉诺塔I

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

    void move(int n, string from, string buffer, string to) {
        //第一步:递归结束的条件
        if (n == 1) {
            cout << from << "->" << to << endl;  
            return;
        }
        // n-1 个圆盘从 from -> buffer
        move(n - 1, from, to, buffer);
        //将 1 个圆盘从 from -> to
        move(1, from, buffer, to);
        //将 n-1 个圆盘从 buffer -> to
        move(n - 1, buffer, from, to);
    }

    int main() {
        int n; cin >> n; 
        move(n, "A", "B", "C");
    }

递归求波兰表达式

#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long

struct node{
    string s; 
    int kind; 
    int lson, rson; // 整理成二叉树结构,可以方便日后访问
} t[N]; 
int cnt = 1; 

double dfs(int now){ 
    cin >> t[now].s; 
    if(!isdigit(t[now].s[0])){
        t[now].kind = 0; 
        t[now].lson = ++cnt; 
        t[now].rson = ++cnt; 
        if(t[now].s[0] == '+') 
            return dfs(t[now].lson) + dfs(t[now].rson); 
        else if(t[now].s[0] == '-')
            return dfs(t[now].lson) - dfs(t[now].rson); 
        else if(t[now].s[0] == '*')
            return dfs(t[now].lson) * dfs(t[now].rson); 
        else return dfs(t[now].lson) / dfs(t[now].rson); 
    }
    else{
        return stof(t[now].s); 
    }
    return 0.0; 
}


int main(){
    printf("%lf", dfs(1)); 
    return 0; 
}

2的幂次方表示

#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long

int n; 

bool cmp(int a, int b){
    return a > b; 
}

string dfs(int n){
    string s = ""; 
    vector <int> G; 
    int cnt = 0; 
    int tmp = n; 
    while(tmp){
        if(tmp % 2 == 1){
            G.push_back(cnt); 
        }
        tmp >>= 1;  
        cnt++; 
    }
    sort(G.begin(), G.end(), cmp); 
    for(int i = 0; i < G.size(); i++){
        if(G[i] == 0) s += "2(0)";
        else if(G[i] == 1) s += "2"; 
        else if(G[i] == 2) s += "2(2)"; 
        else{
            s += "2("; 
            s += dfs(G[i]); 
            s += ")"; 
        }
        if(i != G.size() - 1) s += "+"; 
    }
    return s; 
}

int main(){
    cin >> n; 
    // cout << 
    cout << dfs(n) << endl; 
    return 0; 
}

算24

#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define ll long long

int opr[4]; 
int a[5]; 
bool flag = 0; 


bool vis[5]; 
double dfs2(int now, double alr){
    if(now == 9){
        if(abs(abs(alr) - 24.00) < 1e-8){
            // cout << alr << endl; 
            flag = 1; 
        }
        return 0.00; 
    }
    for(int i = 1; i <= 4; i++){
        if(!vis[i]){
            vis[i] = 1; 
            if(now / 2 == 0) dfs2(now + 2, a[i]); 
            else{
                if(opr[now / 2] == 1) dfs2(now + 2, alr + a[i]); 
                else if(opr[now / 2] == 2) dfs2(now + 2, alr - a[i]); 
                else if(opr[now / 2] == 3) dfs2(now + 2, alr * a[i]); 
                else if(opr[now / 2] == 4) dfs2(now + 2, alr / a[i]); 
            }
            vis[i] = 0; 
        }
    }
    return 0.00; 
}

void dfs1(int now){
    if(flag) return ; 
    if(now == 4){
        dfs2(1, 0.00); 
        return ; 
    }
    for(int i = 1; i <= 4; i++){
        opr[now] = i; 
        dfs1(now + 1); 
    }
    return ; 
}

int main(){
    while(cin >> a[1] >> a[2] >> a[3] >> a[4] && (a[1] | a[2] | a[3] | a[4]) != 0){
        flag = 0; 
        dfs1(1);
        if(flag){
            puts("YES"); 
        }
        else puts("NO"); 
    }
    return 0; 
}

汉诺塔II

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

    map<string, int> g;  

    stack <int> stac[3]; 
    void move(int n, int id, string from, string buffer, string to) {
        //第一步:递归结束的条件
        if (n == 1) {
            cout << id << ":" << from << "->" << to << endl;  
            // stac[g[to]].push(stac[g[from]].top()); 
            // stac[g[from]].pop(); 
            return;
        }
        move(n - 1, id, from, to, buffer);
        int newid = id + n - 1; 
        move(1, newid, from, buffer, to);
        move(n - 1, id, buffer, from, to);
    }

    int main() {
        int n; cin >> n; 
        string a, b, c; 
        cin >> a >> b >> c; 
        g[a] = 0, g[b] = 1, g[c] = 2; 
        for(int i = 1; i <= n; i++)
            stac[g[a]].push(n - i + 1); 
        move(n, 1, a, b, c);
        return 0; 
    }

DFS试炼之排列数字

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

int n; 
vector <int> G; 
 
int ans = 0; 
bool vis[N]; 

void dfs(int now){
    if(now == n + 1){
        string s; 
        for(auto it : G){
            printf("%d ", it); 
        }
        printf("\n"); 
        return ; 

    }
    for(int i = 1; i <= n; i++){
        if(vis[i]) continue; 
        vis[i] = 1; 
        G.push_back(i); 
        dfs(now + 1); 
        G.pop_back(); 
        vis[i] = 0; 
    }
    return ; 
}

int main(){
    cin >> n; 
    dfs(1); 
    return 0; 
}

字符全排列

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

string s;
bool vis[N];  

set <string> G; 
vector <char> t; 

void dfs(int now){
    if(now == s.length() + 1){
        string tmp; 
        for(int i = 0; i < t.size(); i++)
            tmp += t[i]; 
        G.insert(tmp); 
        return ; 
    }
    for(int i = 0; i < s.length(); i++){
        if(vis[i]) continue; 
        t.push_back(s[i]);
        vis[i] = 1; 
        dfs(now + 1); 
        t.pop_back(); 
        vis[i] = 0; 
    }
    return ; 
}

int main(){
    cin >> s; 
    dfs(1); 
    for(auto it : G){
        cout << it << endl; 
    }
    return 0; 
}

DFS试炼之n皇后问题

#include <iostream>
using namespace std;
const int N = 20; 
 
int n;
char g[N][N];
bool col[N], dg[N], udg[N];
 
void dfs(int u) {
    if (u == n) {
        for (int i = 0; i < n; i ++ ) puts(g[i]);  
        puts(""); 
        return;
    }
    int x = u;
    for (int y = 0; y < n; y ++ )
        if (col[y] == false && dg[y - x + n] == false && udg[y + x] == false) {
            col[y] = dg[y - x + n] = udg[y + x] = true;
            g[x][y] = 'Q';
            dfs(x + 1);
            g[x][y] = '.';  // 恢复现场
            col[y] = dg[y - x + n] = udg[y + x] = false;
        }
}
 
int main() {
    cin >> n;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            g[i][j] = '.';
 
    dfs(0);
 
    return 0;
}

拨钟问题

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

string s[10] = {"", "1245", "123", "2356", "147", "24568", "369", "4578", "789", "5689"};  
int tim[10]; 

int minn = 1e9; 
vector <int> G; 
vector <int> ans; 

void change(int x, int flag){ // 第x个钟转. 1: 正转  -1: 反转
    tim[x] += flag;  
    if(tim[x] < 0) tim[x] += 4; 
    tim[x] %= 4; 
    return ; 
}

bool check(){
    for(int i = 1; i <= 9; i++) 
        if(tim[i] != 0) return 0; 
    return 1; 
}

void dfs(int now, int cnt){
    if(now == 10){
        if(check()){
            if(cnt < minn){
                ans = G; 
                minn = cnt; 
            }
        }
        return ; 
    }
    for(int i = 0; i <= 3; i++){
        for(int j = 0; j < s[now].length(); j++){
            for(int h = 1; h <= i; h++){
                change(s[now][j] - '0', 1); 
            }
        }
        for(int j = 1; j <= i; j++)
            G.push_back(now); 
        dfs(now + 1, cnt + i);
        for(int j = 1; j <= i; j++)
            G.pop_back();  
        for(int j = 0; j < s[now].length(); j++){
            for(int h = 1; h <= i; h++){
                change(s[now][j] - '0', -1); 
            }
        }
    }
}

int main(){
    for(int i = 1; i <= 9; i++)
        cin >> tim[i]; 
\
    dfs(1, 0); 
    for(auto it : ans){
        cout << it << " "; 
    }
    return 0; 
}

爬天梯

#include <bits/stdc++.h>
using namespace std;
#define N 100010
#define ll long long

int n; 
int cnt = 0; 

ll f[N]; 

void dfs(int now){
    if(now == 0){
    	f[0] = 1; 
        return ; 
    }
    if(now == 1){
    	f[1] = 1; 
        dfs(0); 
        return ; 
    }
    for(int i = 1; i <= 2; i++){
    	if(f[now - i]) f[now] += f[now - i]; 
    	else dfs(now - i), f[now] += f[now - i]; 
	}
        
    return ; 
}

int main(){
    cin >> n; 
    dfs(n); 
    cout << f[n] << endl; 
    return 0; 
}

放苹果

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

int m, n; 

set <multiset <int> > G; 
vector <int> t; 

void dfs(int now, int k){
    if(now == n + 1){
        multiset <int> s; 
        for(int i = 0; i < t.size(); i++)
            s.insert(t[i]);
        G.insert(s); 
        return ; 
    }
    if(now == n){
        t.push_back(k); 
        dfs(now + 1, 0); 
        t.pop_back(); 
        return ; 
    }
//    printf("now: %d\n", now); 
    for(int i = 0; i <= k; i++){
        t.push_back(i); 
        dfs(now + 1, k - i); 
        t.pop_back(); 
    }
    return ; 
}

int main(){
//	freopen("hh.txt", "r", stdin);  
    int T; cin >> T; 
    while(T--){
        cin >> m >> n; 
        if(m == 0){
            cout << 1 << endl; 
            continue; 
        }
        if(n == 0){
        	cout << 0 << endl; 
        	continue; 
		}
        dfs(1, m);
        cout << G.size() << endl; 
        G.clear();  
    }
    return 0; 
}

第三部分

快速选择第k个数

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

int n, k; 
int a[N]; 

int quickSearch(int l, int r, int k){
    if(l == r){
        return a[l]; 
    }
    int lim = a[l]; 
    int p = l, q = r; 
    while(p < q){
        while(a[p] < lim && p < q) p++; 
        while(a[q] > lim && q > p) q--; 
        if(p < q) swap(a[p], a[q]); 
    }
    int len = r - l + 1; 
    if(p - l + 1 >= k){
        return quickSearch(l, p, k); 
    }
    else return quickSearch(p + 1, r, k - (p - l + 1)); 
}

int main(){
//	freopen("hh.txt", "r", stdin); 
    cin >> n >> k; 
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    cout << quickSearch(1, n, k) << endl; 
    return 0; 
}

求排列逆序数

#include <bits/stdc++.h>
using namespace std;
#define N 100010
#define ll long long

int a[N]; 
int b[N]; 
int n, k; 
ll ans = 0; 

void merge(int l, int r){
    if(l == r){
        return ; 
    }
    int mid = l + r >> 1; 
    int p = l, q = mid + 1; 
    merge(l, mid); 
    merge(mid + 1, r); 
    int cnt = l; 
    while(p <= mid && q <= r){
        if(a[p] <= a[q]){
            b[cnt++] = a[p++]; 
        }
        else{
            ans += mid - p + 1; 
            b[cnt++] = a[q++]; 
        }
    }
    while(p <= mid)
        b[cnt++] = a[p++]; 
    while(q <= r)
        b[cnt++] = a[q++]; 
    for(int i = l; i <= r; i++)
        a[i] = b[i];
    return ; 
}

int main(){
    cin >> n; 
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    merge(1, n); 
    cout << ans << endl; 
    return 0; 
}
posted @ 2023-07-03 15:56  雪之下,树之旁  阅读(192)  评论(0编辑  收藏  举报