1121 Damn Single (25 分)
毫无优化的处理方式,依旧没超时。。。
#include<bits/stdc++.h>
using namespace std;
vector<pair<int, int> > pa;
set<int> ans;
bool f[100005];
int main() {
int n, m;
scanf("%d",&n);
for(int i = 0; i < n; i++) {
int a, b;
scanf("%d %d",&a, &b);
pa.push_back(make_pair(a,b));
}
scanf("%d",&m);
for(int i = 0; i < m; i++) {
int a;
scanf("%d",&a);
f[a] = 1;
ans.insert(a);
}
for(int i = 0; i < n; i++) {
if(f[pa[i].first] && f[pa[i].second]) ans.erase(pa[i].first), ans.erase(pa[i].second);
}
printf("%d\n",ans.size());
int i = 0;
for(auto it: ans) {
if(i++) printf(" ");
printf("%05d",it);
}
return 0;
}
1122 Hamiltonian Cycle (25 分)
测试点2:出现的回路类似1 2 3 1 4 5 1(万一没对起点进行特判就出错了)
#include<bits/stdc++.h>
using namespace std;
bool v[305][305];
int cnt[305];
int main() {
int n, m, a, b, k, st;
scanf("%d %d",&n, &m);
for(int i = 0; i < m; i++) {
scanf("%d %d",&a, &b);
v[a][b] = v[b][a] = 1;
}
scanf("%d",&k);
while(k--) {
bool f = 0;
memset(cnt, 0, sizeof(cnt));
scanf("%d",&a);
if(a != n+1) f = 1;
int pre;
for(int i = 0; i < a; i++) {
scanf("%d",&b);
if(f) continue;
if(!i) st = b;
else if(v[pre][b] == 0) f = 1;
if(cnt[b] && b != st) f = 1;
cnt[b] ++;
pre = b;
}
if(st != b || f || cnt[st] > 2) printf("NO\n");
else printf("YES\n");
}
return 0;
}
1123 Is It a Complete AVL Tree (30 分)
类似1066的一题AVL树操作,没什么特别的难点,但是因为涉及函数很多,又有指针操作,写错了很难找错,写的时候要细心一点
#include<bits/stdc++.h>
using namespace std;
vector<int> ans;
int maxInd;
struct node{
int val, height;
node *l, *r;
};
node* New(int x) {
node* t = new node;
t->val = x;
t->height = 1;
t->l = t->r = NULL;
return t;
}
int getH(node* root) {
if(root == NULL) return 0;
return root->height;
}
int getB(node* root) {
return getH(root->l) - getH(root->r);
}
void update(node* &root) {
root->height = max(getH(root->l) , getH(root->r)) + 1;
}
void L(node* &root) {
node* tmp = root->r;
root->r = tmp->l;
tmp->l = root;
update(root);
update(tmp);
root = tmp;
}
void R(node* &root) {
node* tmp = root->l;
root->l = tmp->r;
tmp->r = root;
update(tmp);
update(root);
root = tmp;
}
void insert(node* &root, int x) {
if(root == NULL) {
root = New(x);
return;
}
if(root->val > x) {
insert(root->l, x);
update(root);
if(getB(root) == 2) {
if(getB(root->l) == 1) R(root);
else if(getB(root->l) == -1) {
L(root->l);
R(root);
}
}
}
else {
insert(root->r, x);
update(root);
if(getB(root) == -2) {
if(getB(root->r) == -1) L(root);
else if(getB(root->r) == 1) {
R(root->r);
L(root);
}
}
}
}
void levelorder(node* root) {
queue<pair<node*,int> >q;
q.push(make_pair(root, 1));
while(q.size()) {
pair<node*, int> now = q.front();
q.pop();
node* t = now.first;
maxInd = max(maxInd, now.second);
int ind1 = now.second*2, ind2 = ind1+1;
ans.push_back(now.first->val);
if(t->l != NULL) q.push(make_pair(t->l, ind1));
if(t->r != NULL) q.push(make_pair(t->r, ind2));
}
}
int main() {
int n,a;
scanf("%d",&n);
node* root = NULL;
for(int i = 0; i < n; i++) {
scanf("%d",&a);
insert(root, a);
// cout<<root->val<<" "<<a<<endl;
}
levelorder(root);
for(int i = 0; i < ans.size(); i++) {
if(i) printf(" ");
printf("%d",ans[i]);
}
if(maxInd == n) printf("\nYES");
else printf("\nNO");
return 0;
}
1126 Eulerian Path (25 分)
首先判断连通性,不连通一定不是欧拉图了,然后直接数度数为奇数的点即可,2个就是欧拉图,0个就是欧拉环,其他情况也不是欧拉图
#include<bits/stdc++.h>
using namespace std;
int degree[5005], even, odd;
bool v[5005];
vector<int> vec[5005];
void dfs(int x) {
v[x] = 1;
for(int i = 0; i < vec[x].size(); i++) {
int y = vec[x][i];
if(v[y]) continue;
dfs(y);
}
}
int main() {
int n, m, a, b, num = 0;
scanf("%d %d",&n, &m);
for(int i = 0; i < m; i++) {
scanf("%d %d",&a, &b);
vec[a].push_back(b);
vec[b].push_back(a);
degree[a]++;
degree[b]++;
}
for(int i = 1; i <= n; i++) {
if(!v[i]) {
dfs(i);
num++;
}
}
for(int i = 1; i <= n; i++) {
if(i != 1) printf(" ");
printf("%d", degree[i]);
if(degree[i] % 2) odd++;
else even++;
}
printf("\n");
if(num > 1) printf("Non-Eulerian\n");
else {
if(odd == 0) printf("Eulerian\n");
else if(odd == 2) printf("Semi-Eulerian\n");
else printf("Non-Eulerian\n");
}
return 0;
}
1128 N Queens Puzzle (20 分)
判断行列是否重复,没有难点,如果像我一样用数组,记得数组开大点,否则是报答案错误,而不是段错误,找了好久
#include<bits/stdc++.h>
using namespace std;
bool row[1005], line1[2005], line2[2005];
int main() {
int n, k, a;
scanf("%d",&k);
while(k--) {
bool f = 0;
memset(row, 0, sizeof(row));
memset(line1, 0, sizeof(line1));
memset(line2, 0, sizeof(line2));
scanf("%d",&n);
// int pre = -2;
for(int i = 1; i <= n; i++) {//第i列
scanf("%d",&a);//第a行
if(f) continue;
if(row[a] || line1[a+i] || line2[(n+i-a)%(2*n)]) f = 1;
row[a] = line1[a+i] = line2[(n+i-a)%(2*n)] = 1;
}
if(f) printf("NO\n");
else printf("YES\n");
}
return 0;
}
/*
5
8 4 6 8 2 7 1 3 5
9 4 6 7 2 8 1 9 5 3
6 1 5 2 6 4 3
5 1 3 5 2 4
6 1 5 3 6 2 4
*/
1129 Recommendation System (25 分)
直接用set排序了,并没有超时。。。
就是每次注意一下先删再加和输出的数不要超过k个即可
#include<bits/stdc++.h>
using namespace std;
const int N = 5e4 + 5;
set<int> id[N];
int num[N], ma;
int main() {
int n, k, a;
scanf("%d %d",&n, &k);
for(int i = 0; i < n; i++) {
scanf("%d",&a);
if(i) {
printf("%d:",a);
for(int i = 0, j = ma; i < k && j > 0; j--) {
for(auto it: id[j]){
if(i < k)i++;
else break;
printf(" %d",it);
}
}
printf("\n");
}
id[num[a]].erase(a);
num[a]++;
ma = max(ma, num[a]);
id[num[a]].insert(a);
}
return 0;
}