|
2010年9月13日
摘要: 题目大意: 输入给出三种操作: 1、add x y&n... 阅读全文
2010年5月17日
2010年5月6日
题目大意: 有N头牛,站在X轴上,没有共点的情况,每个牛有一个听力值V(i),他们交流所消耗的最少volume为abs(X(i)-(X(j)))*MAX{V(i),V(j)} 最后再求总和。 由于数据量最大为20000,显然O(n^2)的算法会超时。先按V值进行从小到大排序可解决MAX的问题,最后就是对每头牛求V值小于他的权值了。 对于第i个牛,在0~i-1中,用两个数状数组,a表示坐标小于x[i]的个数,b表示坐标小于x[i]的牛的坐标之和,另外c表示0~i-1中所有牛的坐标之和。
1long long solve() 2{ 3 long long ans=0,c=dd[0].id; 4 5 update(a,dd[0].id,1); 6 update(b,dd[0].id,dd[0].id); 7 8 long long p,q; 9 for(int i=1;i<n;i++){ 10 p=get_sum(a,dd[i].id); 11 q=get_sum(b,dd[i].id); 12 ans+=dd[i].v*(dd[i].id*p-q+(c-q)-dd[i].id*(i-p)); 13 update(a,dd[i].id,1); 14 update(b,dd[i].id,dd[i].id); 15 c+=dd[i].id; 16 } 17 return ans; 18}
2010年5月4日
摘要: 题目大意: 有N个工件要在M个机器上加工,有一个N*M的矩阵描述其加工时间。 同一时间内每个机器只能加工一个工件,问加工完所有工件后,使得平均加工时间最小。 将工件作为二分图中X部的点,总共N个。 将每个机器拆成... 阅读全文
摘要: 这是我有史以来写得最长的一个程序,前段时间就看了这个题,在网上搜了一下算法,当时看得还有点不太明白,大牛也都说这题代码太长不好写,开始写了一些,后面发现不会写了,就放下了。昨天又来看这个题,居然写出来了,不过还是花了我一个晚上的时间来调试,开始交一次结果就RE了,后来在网上找来了官方数据一个一个的运行才发现找圈DFS的时候陷入了死循环,加了一个标志变量,还是WA,后来反复看解思路才知道换边的时候每... 阅读全文
2010年5月3日
题目大意:从一点经过所有的边两次,且两次的方向不同,又回到起始点,典型的欧拉回路题
1#include<iostream> 2using namespace std; 3#define N 10005 4struct node{ 5 int v; 6 bool flag; 7 node *next; 8}; 9 10node *dd[N]; 11node set[10*N]; 12int n,m; 13 14void init() 15{ 16 memset(dd,0,sizeof(dd)); 17 scanf("%d%d",&n,&m); 18 int u,v; 19 for(int i=1;i<=m;i++){ 20 scanf("%d%d",&u,&v); 21 set[i].v=v; 22 set[i].flag=false; 23 set[i].next=dd[u]; 24 dd[u]=&set[i]; 25 26 set[i+m].v=u; 27 set[i+m].flag=false; 28 set[i+m].next=dd[v]; 29 dd[v]=&set[i+m]; 30 } 31} 32 33void dfs(int k) 34{ 35 node *p=dd[k]; 36 while(p){ 37 if(p->flag==false){ 38 p->flag=true; 39 dfs(p->v); 40 } 41 p=p->next; 42 } 43 printf("%d\n",k); 44} 45 46int main() 47{ 48 init(); 49 dfs(1); 50 return 0; 51}
2010年5月2日
这是一道典型的欧拉回路的题,第一次做这种题,参考了一下别人的代码,结果WA了一晚上,最后照着别人的代码一步一步的改,最后才发现有存在x==y的情况 真是杯具,浪费了一晚上的时间
1#include<iostream> 2#include<algorithm> 3using namespace std; 4 5struct node{ 6 int v; 7 int str; 8}; 9 10node dd[50][2000]; 11bool mark[2000]; 12int stack[2000]; 13int d[50]; 14int size; 15int end; 16 17 18void dfs(int k) 19{ 20 for(int i=1;i<=dd[k][0].v;i++){ 21 if(!mark[dd[k][i].str]){ 22 mark[dd[k][i].str]=true; 23 dfs(dd[k][i].v); 24 stack[++size]=dd[k][i].str; 25 } 26 } 27} 28 29int main() 30{ 31 int x,y,z,start; 32 while(cin>>x>>y&&y){ 33 memset(mark,false,sizeof(mark)); 34 memset(stack,0,sizeof(stack)); 35 memset(d,0,sizeof(d)); 36 size=0; 37 start=x,end=x; 38 39 start=min(x,start); 40 41 end=max(x,end); 42 43 for(int i=0;i<50;i++) 44 dd[i][0].v=0; 45 do{ 46 end=max(end,x); 47 end=max(end,y); 48 cin>>z; 49 d[x]++; 50 d[y]++; 51 52 dd[x][0].v++; 53 dd[x][dd[x][0].v].v=y; 54 dd[x][dd[x][0].v].str=z; 55 56 dd[y][0].v++; 57 dd[y][dd[y][0].v].v=x; 58 dd[y][dd[y][0].v].str=z; 59 }while(cin>>x>>y&&y); 60 bool flag=false; 61 for(int i=1;i<=end;i++) 62 if(d[i]%2) flag=true; 63 if(flag) printf("Round trip does not exist.\n"); 64 else{ 65 dfs(start); 66 67 for(int i=size;i>0;i--) 68 printf("%d ",stack[i]); 69 putchar('\n'); 70 } 71 } 72 return 0; 74} 75 76
2010年4月24日
题目大意:给定一个二叉树,求让它成为孩子结点值不大于父亲结点值,同时左孩子结点值小于右孩子结点值。 用广搜建立二叉树,再后序遍历,求最长不下降子序列,我做了一点变化,将左右孩子交换后先序遍历后求最长不上升子序列。 开始超时了,后来把队列用数组实现就行了,不过注意一下没有右孩子时,左孩子可以和父亲结点值相等。
1//poj 3214 2#include<iostream> 3#include<queue> 4using namespace std; 5#define N 10000000 6 7struct Tree{ 8 int v; 9 Tree *left; 10 Tree *right; 11 void init(){ 12 left=0; 13 right=0; 14 } 15}; 16 17Tree set[N],*p; 18int n,m,cot,len=1; 19int b[N]; 20Tree *myque[N]; 21 22void dfs(Tree *q) 23{ 24 int x; 25 x=q->v+cot,m++; 26 //LIS 27 int low=1,high=len,mid; 28 while(low<=high){ 29 mid=(low+high)/2; 30 if(b[mid]<x) high=mid-1; 31 else low=mid+1; 32 } 33 b[low]=x; 34 if(low>len) len++; 35 36 if(q->right) 37 dfs(q->right); 38 if(q->left){ 39 if(q->right) cot++; //存在左孩子时才将cot++ 40 dfs(q->left); 41 } 42} 43 44int main() 45{ 46 int v; 47 int low=0,high=0; 48 n=0; 49 scanf("%d",&m); 50 set[0].init(); 51 scanf("%d",&set[0].v); 52 myque[high++]=&set[0]; 53 while(scanf("%d",&v)!=EOF){ 54 p=myque[low++]; 55 set[++n].init(); 56 set[n].v=v; 57 p->left=&set[n]; 58 myque[high++]=p->left; 59 if(scanf("%d",&v)!=EOF){ //注意可能不是满二叉树 60 set[++n].init(); 61 set[n].v=v; 62 p->right=&set[n]; 63 myque[high++]=p->right; 64 } 65 else break; 66 } 67 m=0,cot=0; 68 dfs(&set[0]); 69 printf("%d\n",m-len); 70 return 0; 71} 72
2010年4月17日
摘要: 前段时间学会了trie树之后,今天终于学习了一下AC自动机,这个还是挺难学的,现在我还是有点不太懂,参照了网上的代码才把这道题给A了。让我自己背着写出来还不一定会写。这里有一篇比较好的介绍AC自动机的文章http://www.cppblog.com/mythit/archive/2009/04/21/80633.html先看一下这道题吧,大意是给我们一部字典和一个模式串,让我们求出字典中有多少个单... 阅读全文
又贡献了一版的WA和TLE一道题,本来不是很难,但是由于初始化有问题,一直RE。 先说说这道题的思路吧,两次dfs进行缩点,缩点之后再深搜一次找出最长路径与缩点之后的顶点数相比, 相等则输出Yes,否则输出No。
#include<iostream> using namespace std;
struct node{ int v; node *next; };
node pp[6005],qq[6005]; node *dd[1005],*rd[1005]; bool mark[1005]; bool map[1005][1005]; int cal[1005]; int ret[1005]; int n,m,ti;
void init() { memset(mark,false,sizeof(mark)); memset(cal,0,sizeof(cal)); memset(dd,0,sizeof(dd)); memset(rd,0,sizeof(rd)); memset(ret,0,sizeof(ret)); memset(map,false,sizeof(map)); }
void input() { int u,v,i; scanf("%d%d",&n,&m); for(i=0;i<m;i++){ scanf("%d%d",&u,&v); pp[i].v=v; pp[i].next=dd[u]; dd[u]=&pp[i]; qq[i].v=u; qq[i].next=rd[v]; rd[v]=&qq[i]; } }
void dfs(int k) { mark[k]=true; node *p=dd[k]; while(p){ if(!mark[p->v]) dfs(p->v); p=p->next; } cal[++ti]=k; }
void rdfs(int k){ ret[k]=ti; node *p=rd[k]; while(p){ if(!ret[p->v]) rdfs(p->v); else if(ti!=ret[p->v]){ map[ti][ret[p->v]]=true; } p=p->next; } }
int dfsr(int k){ int ans=0; for(int i=1;i<=ti;i++){ if(map[k][i]){ if(!cal[i]) dfsr(i); ans=max(ans,cal[i]); } } cal[k]=ans+1; return cal[k]; }
int main() { int t,i; scanf("%d",&t); while(t--){ init(); input(); ti=0; for(i=1;i<=n;i++) if(!mark[i]) dfs(i); for(ti=0,i=n;i>0;i--){ if(!ret[cal[i]]){ ti++; rdfs(cal[i]); } } int ans=0; memset(cal,0,sizeof(cal)); for(i=1;i<=ti;i++){ if(!cal[i]) dfsr(i); ans=max(ans,cal[i]); } if(ans==ti) printf("Yes\n"); else printf("No\n"); } return 0; }
|