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;
}