牛客网Wannafly挑战赛27部分题解

number1:求完全平方数的个数

“White shores, and beyond. A far green country under a swift sunrise.”--灰魔法师

给出长度为n的序列a, 求有多少对数对 (i, j) (1 <= i < j <= n) 满足 ai + aj 为完全平方数。

这个题暴力求肯定会超时。知道数字的取值范围就知道最大平方数是多少,然后通过平方数来求是否有两个数相加,得到这个数;

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 10;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const ll mod = 1e9 + 7;
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
int n;
int a[100100];
int b[maxn];
int main(){
	scanf("%d",&n);
	memset(b, 0, sizeof(b));
	For(i, 1, n){
		scanf("%d",&a[i]);
		b[a[i]] ++;
	}
	ll ans = 0;
	For(i, 2, 500){
		For(j, 1, n){
			int res = i*i - a[j];
			if(res > 0)
			if(b[res] > 0){
				if(res == a[j]){
					ans += (b[res]-1);
				}else{
					ans += b[res];
				}
			}
		}
		
	}
	
	printf("%lld\n",ans/2);
	return 0;
}

比赛结束后看别人的代码,就发现自己的代码还可以改好多。不够好;

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 10;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const ll mod = 1e9 + 7;
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
int n;
int b[maxn];
int main(){
	scanf("%d",&n);
	memset(b, 0, sizeof(b));
	int a;
	For(i, 1, n){
		scanf("%d",&a);
		b[a] ++;
	}
	ll ans = 0;
	For(i, 1, 500){
		int res = i*i; 
		for(int j = 1; j * 2 < res; j++)ans += (ll)b[j]*b[res - j];
		if(res % 2 == 0) ans += (ll) b[res/2]*(b[res/2]-1)/2;
	}
	printf("%lld\n",ans);
	return 0;
}

number2:这道题就是由给出的边判断是否有奇数环。如果存在输出3,否则输出2,特判一下如果只有一个点的话就输出1;

这个判断就是可以使用并查集来判断

链接:https://www.nowcoder.com/acm/contest/215/B
来源:牛客网
 

给出一棵仙人掌(每条边最多被包含于一个环,无自环,无重边,保证连通),要求用最少的颜色对其顶点染色,满足每条边两个端点的颜色不同,输出最小颜色数即可

输入描述:

第一行包括两个整数n,m,表示顶点数和边数
n <= 100000, m <= 200000
接下来m行每行两个整数u,v,表示u,v之间有一条无向边,保证数据合法

输出描述:

一行一个整数表示最小颜色数

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const ll mod = 1e9 + 7;
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}

int p[maxn], s[maxn];
int ans;
void init(){
	memset(s,1,sizeof(s));
	for(int i = 0; i < maxn; i++) p[i] = i;
	return ;
}

int finds(int x){
	return x == p[x] ? x: p[x] = finds(p[x]);
}

void unions(int x, int y){
	x = finds(x);
	y = finds(y);
	if(x != y){
		p[x] = y;
		s[y] += s[x];
	}else{
		if(s[x]&1) ans = 3;
	}
}
int n,m;
int main(){
	init();
	scanf("%d%d",&n,&m);
	int x, y;
	ans = 2;
	for(int i = 0; i < m; i++){
		scanf("%d%d",&x,&y);
		unions(x,y);
	}
	if(n == 1){
		printf("1\n");
		return 0;
	}else printf("%d\n",ans);
	return 0;
}

在看其他人是还有其他方法。使用的是黑白染色判断dfs不是太会,看懂后会补上的。

猜你喜欢

转载自blog.csdn.net/ab1605014317/article/details/83449025
今日推荐