感觉还可以,学习到了几个新知识,然后出现的问题也挺多
A题解题思路:
- 二分图染色,关键是dfs怎么去搜索
- 首先我们用邻接表存储边信息,然后我们对于给予的好或坏直接进行搜索
- 搜索前我们首先要判断他们的好坏,如果冲突,那么flag = 0, 然后我们去搜索,这里要有个返回值,避免成环
3 | 3 | 1 | 0 |
---|---|---|---|
1 | 2 | ||
2 | 3 | ||
3 | 1 | ||
1 |
- 这种情况就会错误,所以要在搜索的时候就判断(很关键)
- 然后剩下的就排着搜索那种存在但是还没搜索过的点,可能是单点
- 最终判断一下所有的点是否都存在,如果有的不存在那么就flag = 0
注意:
- 注意搜索的条件
- 记住不要break中断输入
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
bool st[N];
int h[N], ne[N], e[N], color[N], idx;
void add(int x, int y){
e[idx] = y, ne[idx] = h[x], h[x] = idx++;
}
bool dfs(int u, int c){
color[u] = c;
for (int i = h[u]; i != -1; i = ne[i]){
int j = e[i];
if (!color[j]){
if (!dfs(j,3 - c)) return false;
}
else if (color[j] == c) return false;
}
return true;
}
int main(){
// 1 为好的类 , 2为不好的类
int n, m, a, b;
while(scanf("%d%d%d%d",&n,&m,&a,&b)!=EOF){
idx = 0;
memset(h,-1,sizeof h);
memset(color, 0, sizeof color);
memset(st, false, sizeof st);
for (int i = 0; i < m; i++){
int x, y;
scanf("%d%d",&x,&y);
st[x] = true;
st[y] = true;
add(x,y), add(y,x);
}
int flag = 1;
for (int i = 0 ; i < a; i ++){
int t;
scanf("%d",&t);
st[t] = true;
if(color[t] == 2){
flag = 0;
}
if (!dfs(t,1)) flag = 0;
}
for (int i = 0 ; i < b; i ++){
int t;
scanf("%d",&t);
st[t] = true;
if (color[t] == 1){
flag = 0;
}
if(!dfs(t,2)) flag = 0;
}
for (int i = 1; i <= n; i++){
if (!color[i] && st[i]){
if (!dfs(i,1)){
flag = 0;
break;
}
}
}
for (int i = 1; i <= n; i++){
if (!st[i] || !color[i]){
flag = 0;
}
}
if (!flag) puts("NO");
else puts("YES");
}
return 0;
}
C题解题思路:
- 威佐夫博弈 + 高精度
- 首先威佐夫博弈我也不会,这个博弈有一个结论
- 感觉很神奇(推理每太看懂)
- 然后大数的话用的java,相当于一个大数的板子吧,到时候学习学习
代码:
import java.math.BigInteger;
import java.util.Scanner;
import java.math.BigDecimal ;
public class Main {
//对常数开方保留多位小数,返回高精度小数
private static BigDecimal sqrt(BigDecimal x, int n) {
BigDecimal ans = BigDecimal.ZERO;
BigDecimal eps = BigDecimal.ONE;
for (int i = 0; i < n; ++i) {
while (ans.pow(2).compareTo(x) < 0) {
ans = ans.add(eps);
}
ans = ans.subtract(eps);
eps = eps.divide(BigDecimal.TEN);
}
return ans;
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
BigDecimal a = cin.nextBigDecimal();
BigDecimal b = cin.nextBigDecimal();
BigDecimal c = sqrt(new BigDecimal(5), 120);
c = c.add(BigDecimal.ONE).divide(new BigDecimal(2));
BigDecimal t = null;
if(a.compareTo(b) == 1) {
t = a;
a = b;
b = t;
}
//计算(bk - ak ) * (1+sqrt(5))/2 == ak是否成立 左边向下取整
if( b.subtract(a).multiply(c).setScale(0, BigDecimal.ROUND_DOWN).equals(a)) {
System.out.println(0);
}
else
System.out.println(1);
}
cin.close();
}
}