题解:
2cosx=2cosx
2cos2x=(2cosx)^2-2
2cos3x=(2cosx)^3-3*(2cosx)
数归证明2cos(nx)能表示成关于2cosx的多项式,设为f(n)
f(1)=x,f(2)=x^2-2(其中的x就是2cosx)
假设n=1~k时均成立(k>=3)
当n=k+1时
由cos((k+1)x)=cos(kx)cos(x)-sin(kx)sin(x)
cos((k-1)x)=cos(kx)cos(x)+sin(kx)sin(x)
相加得到cos((k+1)x)+cos((k-1)x)=cos(kx)*2cos(x)
从而f(k+1)+f(k-1)=f(k)*x
-> f(k+1)=f(k)*x-f(k-1)
从而成立
这是我们根据递推关系可知对于项的系数和 也满足这个关系式
g(1)=1,g(2)=-1.....于是求这个数列的通项即可。
然后求出循环节:1, -1, -2, -1, 1, 2……
//yy:我第一遍看这题没看懂题目表达的意思。。。傻傻
#include<cstdio>using namespace std; typedef long long ll; int a[6] = {1, -1, -2, -1, 1, 2}; int main() { ll x; scanf("%lld", &x); printf("%d ", a[(x-1) % 6]); return 0; }
--------------------------------------------------------------------------------------------------------------------
又做了一遍几道以前做过的水题,卖萌。。。
poj1611 The Suspects 【并查集】
题意:有N个学生,编号为0-N-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染,并且这些人如果还参加了别的社团,他所在的社团照样全部感染,求感染的人数。
题解:求0号所在的强连通图的结点数。并查集。
我的:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<cmath> #define CLR(a,b) memset((a),(b),sizeof((a))) using namespace std; const int N = 30005; int n, m; int fa[N], rk[N]; void init() { for(int i = 0; i < n; ++i) { fa[i] = i; rk[i] = 1; } } int fin(int x) { if(fa[x] != x) fa[x] = fin(fa[x]); return fa[x]; } void join(int x, int y) { if((x = fin(x)) == (y = fin(y))) return; fa[x] = y; rk[y] += rk[x];//第一遍手残写成rk[y]++ } int main () { int i, j, x, y, cnt, ans; while(~scanf("%d%d", &n, &m), n || m) { init(); for(i = 0; i < m; ++i) { scanf("%d", &cnt); scanf("%d", &x); for(j = 1; j < cnt; ++j) { scanf("%d", &y); join(x, y); } } ans = rk[fin(0)]; printf("%d ", ans); } return 0; }
学弟的代码WA了,然后把判断父节点还是找根那里给他改对了。。。:
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; int pre[30005]; int visit[30005]; int find(int xxx) { if(xxx!=pre[xxx]) return pre[xxx]=find(pre[xxx]); else return xxx; } void join(int ax,int bx) { int axx=find(ax); int bxx=find(bx); if(axx!=bxx) pre[bxx]=axx; } int main() { int n,m; while(~scanf("%d %d",&n,&m)&&n+m) { int i,j; for(i=0;i<n;i++) pre[i]=i; memset(visit,0,sizeof(visit)); visit[0]=1; int ans=1; for(i=1;i<=m;i++) { int x; scanf("%d",&x); int q[30005]; bool f=false; for(j=0;j<x;j++) { scanf("%d",&q[j]); if(find(q[j])==0) f=true; } if(f) { for(j=0;j<x;j++) { join(0,q[j]); } } else { for(j=1;j<x;j++) { join(q[0],q[j]); } } } for(i=1;i<n;i++) { if(find(i)==0) ans++; } printf("%d ",ans); } return 0; }
hdu1878 欧拉回路 【并查集判连通 或 dfs判连通】
并查集判连通, 然后判断欧拉回路:无向图 度数为偶
方法一:并查集
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<cmath> #define CLR(a,b) memset((a),(b),sizeof((a))) using namespace std; const int N = 1005; int fa[N]; int n, m; int cnt; int du[N]; int fin(int x) { if(fa[x] != x) fa[x] = fin(fa[x]); return fa[x];//第一遍写成返回x,心塞,我好蠢啊。。。 } void join(int x, int y) { if((x = fin(x)) == (y = fin(y))) return ; else { fa[x] = y; cnt++; } } int main () { int x, y, i ,j; while(scanf("%d", &n), n) { CLR(du, 0); for(i = 1; i <= n; ++i) fa[i] = i; cnt = 0; scanf("%d", &m); int f = 0; while(m--) { scanf("%d%d", &x, &y); join(x, y); du[x]++; du[y]++; } if(cnt == n-1) { for(i = 1; i <= n; ++i) { if(du[i] % 2 == 1) { f = 1; break; } } if(f) printf("0 "); else printf("1 "); } else printf("0 "); } return 0; }
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<cmath> #define CLR(a,b) memset((a),(b),sizeof((a))) using namespace std; const int N = 1005; int fa[N]; int n, m; int cnt; int du[N]; int fin(int x) { if(fa[x] != x) fa[x] = fin(fa[x]); return fa[x]; } void join(int x, int y) { if((x = fin(x)) == (y = fin(y))) return ; else { fa[x] = y; } } int main () { int x, y, i ,j; while(scanf("%d", &n), n) { CLR(du, 0); for(i = 1; i <= n; ++i) fa[i] = i; cnt = 0; scanf("%d", &m); int f = 0; while(m--) { scanf("%d%d", &x, &y); join(x, y); du[x]++; du[y]++; } for(i = 1; i <= n; ++i) { if(fa[i] == i) cnt++; if(du[i] % 2 == 1) { f = 1; break; } } if(f || cnt != 1) printf("0 "); else printf("1 "); } return 0; }
方法二:dfs
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<cmath> #define CLR(a,b) memset((a),(b),sizeof((a))) using namespace std; const int N = 1005; int n, m; int du[N]; int g[N][N], vis[N]; void dfs(int x) { vis[x] = 1; for(int i = 1; i <= n; ++i) { if(!vis[i] && g[x][i]) dfs(i); } } int main () { int x, y, i ,j; while(scanf("%d", &n), n) { CLR(du, 0); CLR(vis, 0); CLR(g, 0); scanf("%d", &m); int f = 0; while(m--) { scanf("%d%d", &x, &y); g[x][y] = g[y][x] = 1; du[x]++; du[y]++; } dfs(1); for(i = 1; i <= n; ++i) { if(!vis[i] || du[i] % 2 == 1) { f = 1; break; } } if(f) printf("0 "); else printf("1 "); } return 0; }
//yy:记得上回去比赛纠结死在格式错误上,水题各种格式错误,回来后改,有一题把string全部改成char就过了,我现在也不知道哪里错了。。。不贴它了,气哭了。。。
题目链接:L1-039. 古风排版 [水题]
//yy:WA的郁闷,姿势太差……
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<cmath> #include<queue> #include<limits.h> #define CLR(a,b) memset((a),(b),sizeof((a))) using namespace std; typedef long long ll; char s[1005], ans[105][1005]; int main() { int i, j, len, row, col, r, c; scanf("%d ", &row); gets(s); len = strlen(s); /*WA了。。 int t = len % row; col = len / row + t; */ col = len / row + (len % row == 0 ? 0 : 1); for(i = 0; i < row; ++i) {//唉,别漏了啊。。。 ans[i][0] = ' ';//orz ans[i][col] = '