A、类似于拓扑排序,利用异或的性质。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define ll long long;
#define MAXN 65540 //2^16 = 65536
using namespace std;
typedef pair<int, int> P;
int degree[MAXN], s[MAXN], vis[MAXN];
queue<int> q;
queue<P> ans;
int main(){
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++){
scanf("%d%d", °ree[i], &s[i]);
if(degree[i] == 1) q.push(i);
}
while(!q.empty()){
int u = q.front(), v; q.pop();
v = s[u];
if(vis[u]) continue;
ans.push(make_pair(u, v));
s[v] = s[v] ^ u;
degree[v]--;
if(degree[v] == 0) vis[v] = 1;
if(degree[v] == 1) q.push(v);
}
printf("%d\n", ans.size());
while(!ans.empty()){
P p = ans.front(); ans.pop();
printf("%d %d\n", p.first, p.second);
}
return 0;
}
B、背xia包gao
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<vector>
using namespace std;
static const int MAXN = 1005;
int a[MAXN], vis[MAXN];
int main(){
int n, m, Min, ans;
while(scanf("%d", &n) && n != 0){
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
scanf("%d", &m);
if(m < 5){
printf("%d\n", m);
continue;
}
Min = ans = m;
memset(vis, 0, sizeof(vis));
vis[m] = 1;
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++)
{
ans = min(ans , Min - a[i]);
bool flag = false;
for (int j = a[i] + 5; j <= m; j++){
if(!flag && vis[j]){
flag = true;
Min = min(Min, j - a[i]);
}
if(vis[j] == 1) vis[j - a[i]] = 1;
}
}
printf("%d\n", ans);
}
return 0;
}
C、
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long;
#define INF 0x3f3f3f3f
using namespace std;
int a[2050];
int brother(int node){
return node % 2 == 0 ? node + 1 : node - 1;
}
int father(int node){
return node / 2;
}
int main(){
int n, Sum = 0;
scanf("%d", &n);
for (int i = 2; i < pow(2, n + 1); i++)
scanf("%d", &a[i]);
for (int i = pow(2, n + 1) - 1; i > 1; i--){
if(a[i] < a[brother(i)]) Sum += a[brother(i)] - a[i];
if(i & 1) a[father(i)] += max(a[i], a[brother(i)]);
}
printf("%d", Sum);
return 0;
}
D、图,无边变有边
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long;
using namespace std;
int g[510][510], color[510];
int main(){
int n, m, u, v;
scanf("%d%d", &n, &m);
while(m--){
scanf("%d%d", &u, &v);
g[u][v] = g[v][u] = 1;
}
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
if(i == j)
continue;
if(g[i][j] == 0){
if(color[i] == 0) color[i] = 1;
if(color[j] == color[i]){
printf("No");
return 0;
}
color[j] = 4 - color[i];
}
else if(color[i] + color[j] == 4){
printf("No");
return 0;
}
}
}
for (int i = 1; i <= n; i++) if(!color[i]) color[i] = 2;
printf("Yes\n");
for(int i = 1; i <= n; i++) printf("%c", char(color[i] + 'a' - 1));
return 0;
}
E、简单数学 乘变除防溢出
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
int main(){
long long l, r, k;
bool flag = false;
cin >> l >> r >> k;
for (long long i = 1;; i = i * k)
{
if(i >= l){
cout << i << " ";
flag = true;
}
if(k > r / i) break;
}
if(!flag) cout << "-1";
return 0;
}
F、简单数论,辗转相除
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll solve(ll a, ll b){
return b == 0 ? 0 : a / b + solve(b, a % b);
}
int main(){
ll a, b;
scanf("%lld%lld", &a, &b);
printf("%lld", solve(a, b));
return 0;
}
G、将10分解为2*5
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long;
using namespace std;
static const int INF = 0x3f3f3f3f;
typedef struct{
int num2, num5;
} D;
const int dir[2][2] = {{1, 0}, {0, 1}};
D d[1010][1010];
int n, sx, sy;
int a[1010][1010], dp2[1010][1010], dp5[1010][1010], p2[1010][1010], p5[1010][1010];
int count_num(int x, int num){
int cnt = 0;
while(x % num == 0){
x /= num;
cnt++;
}
return cnt;
}
void print2(int x, int y){
if(x == 1 && y == 1) return;
if(p2[x][y] == 0){
print2(x - 1, y);
printf("D");
} else{
print2(x, y - 1);
printf("R");
}
}
void print5(int x, int y){
if(x == 1 && y == 1) return;
if(p5[x][y] == 0){
print5(x - 1, y);
printf("D");
} else{
print5(x, y - 1);
printf("R");
}
}
int main(){
scanf("%d", &n);
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
scanf("%d", &a[i][j]);
if(!a[i][j]){
d[i][j].num2 = d[i][j].num5 = 1;
sx = i, sy = j;
}
else{
dp2[i][j] = dp5[i][j] = INF;
d[i][j].num2 = count_num(a[i][j], 2);
d[i][j].num5 = count_num(a[i][j], 5);
}
}
}
dp2[1][1] = d[1][1].num2;
dp5[1][1] = d[1][1].num5;
for (int x = 1; x <= n; x++){
for (int y = 1; y <= n; y++){
for (int k = 0; k < 2; k++){
int nx = x + dir[k][0], ny = y + dir[k][1];
if(nx > n || ny > n || a[nx][ny] == 0) continue;
if(dp2[x][y] + d[nx][ny].num2 < dp2[nx][ny]){
dp2[nx][ny] = dp2[x][y] + d[nx][ny].num2;
p2[nx][ny] = k;
}
if(dp5[x][y] + d[nx][ny].num5 < dp5[nx][ny]){
dp5[nx][ny] = dp5[x][y] + d[nx][ny].num5;
p5[nx][ny] = k;
}
}
}
}
if(sx > 0 && min(dp2[n][n], dp5[n][n]) > 1){
printf("1\n");
for (int i = 1; i < sx; i++) printf("D");
for (int i = 1; i < n; i++) printf("R");
for (int i = sx; i < n; i++) printf("D");
return 0;
}
if(dp2[n][n] < dp5[n][n]){
printf("%d\n", dp2[n][n]);
print2(n, n);
}
else{
printf("%d\n", dp5[n][n]);
print5(n, n);
}
return 0;
}