这次个人赛的C和D直接给我干懵了,C的话是自己的逻辑混乱了,D是自己写的时候又忘记了以前犯的错误了
C题解题思路
- C题直接枚举,不过有一定的技巧与思维
- 首先我们想,他一般情况下是先枚举一个数字的,然后2个…
- 那么这里有个坑就是,如果有 1 2 3 ,那么我们先枚举完3了,然后再枚举 1 2,那么他的和相同了,肯定是不行的,所以我们这里想从大到小枚举
- 还有一种方法就是,我们保证一些数固定,然去移动一个数字,那么也是可以的,那么怎么去实现。
- 首先我们会枚举一个数,这个数是从大到小移动的(这个大是基于那些不动的数之外的,代码中会展示),所以我们就这样排着数据就可以
代码:
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 55;
int a[N];
int main(){
int n, k;
scanf("%d%d",&n,&k);
for (int i = 1; i <= n; i++){
scanf("%d",&a[i]);
}
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; i++){
for (int j = i; j <= n; j ++){ // 这里注意一下,主要是对输出的值
printf("%d",i);
k --;
for (int l = n; l > n - i + 1; l --){
printf(" %d",a[l]);
}
printf(" %d\n",a[n - j + 1]); // 这里肯定是小于等于 n - i + 1
if (k == 0) break;
}
if (k == 0) break;
}
return 0;
}
D题解题思路:
- 这个题意很难理解啊,他让你求的是,颜色点周围的颜色与当前点的颜色不同的最大数目,这里需要注意,他这个点可能有很多个,所以,这些点周围的点,都算在这个点里。(理解一下)
- 所以这个题网上有直接数组或者map存储的方法,不过最近看到图就整dfs,所以这题也是用dfs写的
- 我们用dfs去遍历,我们存储下当前点如果检查过,下次就不用检查了(因为这里能成环),然后这里我傻了我直接想dfs(1),忘了不一定是联通块,所以应该全部点都dfs一遍,最后1— 1e5遍历颜色即可(注意最后的比较,要求输出相同数量,颜色!! 最小的那个颜色)
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
using namespace std;
const int N = 100010, M = 200010;
int h[N], ne[M], e[M], idx;
int a[N], b[M];
bool st[N], sta[N];
set <int> ans[N];
void add(int x, int y){
e[idx] = y, ne[idx] = h[x], h[x] = idx++;
}
void dfs(int u){
if (st[u]) return;
st[u] = true;
ans[a[u]].insert(a[u]);
for (int i = h[u]; i != -1; i = ne[i]){
int j = e[i];
ans[a[u]].insert(a[j]);
dfs(j);
}
}
int main(){
int n, m;
int k = 1e6;
scanf("%d%d",&n,&m);
memset(h,-1,sizeof h);
for (int i = 1; i <= n; i++){
scanf("%d",&a[i]);
sta[a[i]] = true;
k = min(a[i],k);
}
int cnt = 0;
for (int i = 0; i < m; i++){
int x, y;
scanf("%d%d",&x,&y);
add(x,y), add(y,x);
b[cnt] = x;
cnt++;
b[cnt] = y;
cnt ++;
}
for (int i = 0; i < cnt; i ++){
dfs(b[i]);
}
int mx = -1;
for (int i = 1; i <= 1e5 + 1; i++){
if (sta[i]){
int t = ans[i].size();
t = max(1,t);
if (t > mx){
mx = t;
k = i;
}
}
}
// printf("%d\n",mx);
printf("%d\n",k);
return 0;
}