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不是太会,看懂后会补上的。