啥也别说了

看C++和算法,眼泪哗哗的。。。
 
 

常用链接

  • 我的随笔
  • 我的评论
  • 我参与的随笔

留言簿(4)

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔分类

  • algorithm(14) (rss)
  • pku/acm(59) (rss)
  • 数字图像(1) (rss)

随笔档案

  • 2010年5月 (1)
  • 2010年3月 (5)
  • 2009年3月 (1)
  • 2008年12月 (1)
  • 2008年11月 (66)

搜索

  •  

最新评论

  • 1. re: ACM 2325 Persistent Number 大数相除
  • 大数相除部分,貌似100/20的结果是错的。
  • --Raise
  • 2. re: 字典树原理(转)
  • 一看就是c++外行写的代码,
  • --ddd
  • 3. re: ACM 1664 放苹果
  • 赞。。新手 看了豁然开朗。.。谢谢了
  • --mokuku
  • 4. re: 字典树原理(转)
  • 代码风格不是很好
  • --ygqwna
  • 5. re: 字典树原理(转)[未登录]
  • 只有new,没有delete,必然内存泄露
  • --123

阅读排行榜

  • 1. 字典树原理(转)(7997)
  • 2. STL 堆排序使用和体会(转)(2092)
  • 3. ACM 2325 Persistent Number 大数相除(1887)
  • 4. 二叉树实例(1739)
  • 5. 大概了解cin,cin.getline,cin.clear,cin.ignore,cin.get()的用法(1627)

评论排行榜

  • 1. 字典树原理(转)(7)
  • 2. ACM 1730 Perfect Pth Powers(3)
  • 3. ACM 1929 Calories from Fat(2)
  • 4. ACM 2325 Persistent Number 大数相除(2)
  • 5. ACM 2316 SPIN(2)

Powered by: 博客园
模板提供:沪江博客
C++博客 | 首页 | 发新随笔 | 发新文章 | 联系 | 聚合 | 管理

ACM 1597 Uniform Generator 余数和移动步数的关系
给定a,b,设G=gcd(a,b),于是有a=A*G,b=B*G(1<=A,B,gcd(A,B)=1)
对于a的多次加可以看成K*a(1<=k),转化成(K*a)%b的所有结果能否表示成0..b-1中的所有数,
假(K*a)%b=M,M=K*a-W*b(W为使M>0的最大整数),M=K*A*G-W*B*G M%G==0,
既结果是G的倍数,如果想取得0..b-1中的所有数,
那么必须G=1才可能..
这算法牛X。。。
#include"stdio.h"
int main() 
{ 
long m,n,k,i; 
while(scanf("%ld%ld",&m,&n)!=-1)
{ printf("%10ld%10ld    ",m,n);
    k
=1;
for(i=2;i<=(m>n?n:m);i++) 
{ 
if(m%i==0&&n%i==0) 
k
=i; 
}

 
if(k==1)
     printf(
"Good Choice\n\n");
        
else
            printf(
"Bad Choice\n\n");

}

}

posted @ 2008-11-16 19:58 hunter 阅读(345) | 评论 (0) | 编辑 收藏
 
ACM 1595 Prime Cuts
妈的,没见过那么恶心的题目。。。
首先题目就错了,1不是质数啊!!!
输出之间居然还有一空行。。。
检查了半天都没查出来,杀人了!!!

懒得改了,用了同学的
#include <iostream>
#include 
<vector>
#include 
<string>
#include 
<math.h>
#include 
<iomanip>
#include 
<stdlib.h>
using namespace std;

#include
"stdio.h"
#include
"math.h"
int p[2001];

int main()
{
    
int n,c,n1;
    
int i,j;
    
int tol;
    
int flag;
    
while(scanf("%d%d",&n,&c)!=-1)
    
{


        p[
1]=1;
        tol
=1;
        
for(i=2;i<=3000;i++)
        
{
            flag
=1;
            
for(j=2;j<=(int)sqrt((double)i);j++)
            
{
                
if(i%j==0){flag=0;break;}
            }

            
if(flag==0)continue;
            
else if(i>n)break;
            
else
            
{
                tol
++;
                p[tol]
=i;

            }


        }



        
//此时质数的个数是tol,第一个质数是1
        printf("%d %d:",n,c);
        
if(tol%2==0&&tol>=c*2)
        
{
            
for(i=1;i<=c*2;i++)
            
{
                j
=(tol-c*2)/2;
                printf(
" %d",p[j+i]);

            }

            printf(
"\n\n");
        }


        
if(tol%2==0&&tol<c*2)
        
{
            
for(j=1;j<=tol;j++)
                printf(
" %d",p[j]);
            printf(
"\n\n");
        }


        
if(tol%2==1&&tol>=c*2-1)
        
{
            
for(i=1;i<=c*2-1;i++)
            
{
                j
=(tol-c*2+1)/2;
                printf(
" %d",p[i+j]);
            }

            printf(
"\n\n");
        }


        
if(tol%2==1&&tol<c*2-1)
        
{
            
for(j=1;j<=tol;j++)
            
{
                printf(
" %d",p[j]);
            }

            printf(
"\n\n");
        }




    }

}
posted @ 2008-11-16 15:25 hunter 阅读(420) | 评论 (0) | 编辑 收藏
 
ACM 1579 Function Run Fun
传说中的动态规划。。。
注意题目的优先计算顺序。先是考虑是否会小于0,然后才考虑是否会大于20,要不然就会WA。
哇塞,真的这样,这题太假了。。。

#include <iostream>
#include 
<vector>
#include 
<string>
#include 
<math.h>
#include 
<iomanip>
#include 
<stdlib.h>
using namespace std;

int w[21][21][21];

void init()
{
    
for (int i=0;i<21;i++)
    
{
        
for (int j=0;j<21;j++)
        
{
            
for (int k=0;k<21;k++)
            
{
                
if(i==0||j==0||k==0)
                    w[i][j][k]
=1;
                
else if(i<j&&j<k)
                    w[i][j][k]
=w[i][j][k-1]+w[i][j-1][k-1]-w[i][j-1][k];
                
else
                    w[i][j][k]
=w[i-1][j][k]+w[i-1][j-1][k]+w[i-1][j][k-1]-w[i-1][j-1][k-1];
            }

        }

    }

}

int main()
{
    init();
    
int a,b,c;
    
while (scanf("%d %d %d",&a,&b,&c)!=EOF)
    
{
        
if (a==-1&&b==-1&&c==-1)
        
{break;
        }

        
if (a<=0||b<=0||c<=0)
        
{
            printf(
"w(%d, %d, %d) = %d\n",a,b,c,w[0][0][0]);
        }

        
else if (a>20||b>20||c>20)
        
{
            printf(
"w(%d, %d, %d) = %d\n",a,b,c,w[20][20][20]);
        }

        
else
        
{
            printf(
"w(%d, %d, %d) = %d\n",a,b,c,w[a][b][c]);
        }

    }

}
posted @ 2008-11-16 13:59 hunter 阅读(493) | 评论 (1) | 编辑 收藏
 
字典树原理(转)

Trie树就是字典树,其核心思想就是空间换时间。


举个简单的例子。


给你100000个长度不超过10的单词。对于每一个单词,我们要判断他出没出现过,如果出现了,第一次出现第几个位置。
这题当然可以用hash来,但是我要介绍的是trie树。在某些方面它的用途更大。比如说对于某一个单词,我要询问它的前缀是否出现过。这样hash就不好搞了,而用trie还是很简单。
现在回到例子中,如果我们用最傻的方法,对于每一个单词,我们都要去查找它前面的单词中是否有它。那么这个算法的复杂度就是O(n^2)。显然对于100000的范围难以接受。现在我们换个思路想。假设我要查询的单词是abcd,那么在他前面的单词中,以b,c,d,f之类开头的我显然不必考虑。而只要找以a开头的中是否存在abcd就可以了。同样的,在以a开头中的单词中,我们只要考虑以b作为第二个字母的……这样一个树的模型就渐渐清晰了……
假设有b,abc,abd,bcd,abcd,efg,hii这6个单词,我们构建的树就是这样的。

对于每一个节点,从根遍历到他的过程就是一个单词,如果这个节点被标记为红色,就表示这个单词存在,否则不存在。
那么,对于一个单词,我只要顺着他从跟走到对应的节点,再看这个节点是否被标记为红色就可以知道它是否出现过了。把这个节点标记为红色,就相当于插入了这个单词。
这样一来我们询问和插入可以一起完成,所用时间仅仅为单词长度,在这一个样例,便是10。
我们可以看到,trie树每一层的节点数是26^i级别的。所以为了节省空间。我们用动态链表,或者用数组来模拟动态。空间的花费,不会超过单词数×单词长度。

 

给出一个用类封装的字典树代码,厄。。。做ACM的模板用另一个。。应该放在了“ACM模板”文件夹下了。。。

#include <cstdio>
#include 
<iostream>
#include 
<cstring>
using namespace std;


const int num_chars = 26;


class Trie {
public:
      Trie():root(NULL)
{};
      Trie(Trie
& tr);

     
int search(const char* word, char* entry ) const;
     
int insert(const char* word, const char* entry);
     
int remove(const char* word, char* entry);
private:
     
struct Trie_node
     
{
         
char* data;
          Trie_node
* branch[num_chars];
          Trie_node();
     }
* root;
}
;
Trie::Trie_node::Trie_node() 
{
      data 
= NULL;
    
for (int i=0; i<num_chars; ++i) 
          branch[i] 
= NULL;
}


int Trie::search(const char* word, char* entry ) const 
{
    
int position = 0;
    
char char_code;
     Trie_node 
*location = root;
    
while( location!=NULL && *word!=0 ) 
    
{
        
if (*word>='A' && *word<='Z') 
              char_code 
= *word-'A';
        
else if (*word>='a' && *word<='z') 
              char_code 
= *word-'a';
        
else return 0;


         location 
= location->branch[char_code];
         position
++;
         word
++;
    }

    
if ( location != NULL && location->data != NULL ) 
    
{
        strcpy(entry,location
->data);
        
return 1;
    }

    
else return 0;
}

int Trie::insert(const char* word, const char* entry) 
{
    
int result = 1, position = 0;
    
if ( root == NULL ) root = new Trie_node;
    
char char_code;
      Trie_node 
*location = root;
    
while( location!=NULL && *word!=0 )
    
{
        
if (*word>='A' && *word<='Z') 
              char_code 
= *word-'A';
        
else if (*word>='a' && *word<='z') 
              char_code 
= *word-'a';
        
else return 0;


        
if( location->branch[char_code] == NULL ) 
              location
->branch[char_code] = new Trie_node;


          location 
= location->branch[char_code];
          position
++;
          word
++;
    }

    
if (location->data != NULL)
          result 
= 0;
    
else {
          location
->data = new char[strlen(entry)+1];
        strcpy(location
->data, entry);
    }

    
return result;
}

int main()
{
      Trie t;
      
char entry[100];
      t.insert(
"aa", "DET"); 
      t.insert(
"abacus","NOUN");
      t.insert(
"abalone","NOUN"); 
      t.insert(
"abandon","VERB");
      t.insert(
"abandoned","ADJ"); 
      t.insert(
"abashed","ADJ");
      t.insert(
"abate","VERB"); 
      t.insert(
"this", "PRON");
    
if (t.search("this", entry))
        cout
<<"'this' was found. pos: "<<entry<<endl;
    
if (t.search("abate", entry))
        cout
<<"'abate' is found. pos: "<<entry<<endl;
    
if (t.search("baby", entry))
        cout
<<"'baby' is found. pos: "<<entry<<endl;
    
else
        cout
<<"'baby' does not exist at all!"<<endl;
    
    
if (t.search("aa", entry))
        cout
<<"'aa was found. pos: "<<entry<<endl;
}



PS:实现方法http://met.fzu.edu.cn/eduonline/web/web/resources/articleContent.asp?id=346
posted @ 2008-11-16 11:42 hunter 阅读(7997) | 评论 (7) | 编辑 收藏
 
ACM 1564 Sum it up
     摘要: 今天总算是碰到一道复杂题了。。。(我BT了?)弄死我了,主要是排除重复情况,我想不通,最后参考了前人的代码,修改后AC了。。。思路:通过递归,得出可能存在的解法,并记录,查找原记录,若存在相同则取消记录 #include <iostream>#include <vector>#include <string>#include&nb...  阅读全文
posted @ 2008-11-16 00:19 hunter 阅读(524) | 评论 (1) | 编辑 收藏
 
ACM 1552 Doubles
刚看了qsort的实现,正好碰到一道水题,试试哈。。。AC通过

#include <iostream>
#include 
<string>
#include 
<stdlib.h>
using namespace std;

int cmp(const void* a,const void* b)
{
    
return *(int*)b-*(int*)a;
}

int main()
{
    
int n=0;
    
int input[16];
    cin
>>input[n];
    
while (input[n]!=-1)
    
{
        
while (input[n]!=0)
        
{
            n
++;
            cin
>>input[n];
        }

        qsort(input,n,
sizeof(input[0]),cmp);
        
int count=0;
        
for (int i=0;i<n-1;i++)
        
{
            
if (input[i]%2!=0)
            
{continue;
            }

            
for (int j=i+1;j<n;j++)
            
{
                
if (input[i]/(double)2==input[j])
                
{
                    count
++;
                    
break;
                }

            }

        }

        cout
<<count<<endl;
        
if (input[n]==0)
        
{
            n
=0;
            memset(input,
0,sizeof(input));
        }

        cin
>>input[0];
    }

}
posted @ 2008-11-15 21:58 hunter 阅读(416) | 评论 (0) | 编辑 收藏
 
七种qsort排序方法
<本文中排序都是采用的从小到大排序>
一、对int类型数组排序
程序代码 程序代码
int num[100];
Sample:
int cmp ( const void *a , const void *b )
{
     return *(int *)a - *(int *)b;
}
qsort(num,100,sizeof(num[0]),cmp);

二、对char类型数组排序(同int类型)
程序代码 程序代码
char word[100];
Sample:
int cmp( const void *a , const void *b )
{
    return *(char *)a - *(char*)b;
}
qsort(word,100,sizeof(word[0]),cmp)

三、对double类型数组排序(特别要注意)
程序代码 程序代码
double in[100];
int cmp( const void *a , const void *b )
{
    return *(double *)a > *(double *)b ? 1 : -1;
} qsort(in,100,sizeof(in[0]),cmp);
 
四、对结构体一级排序
程序代码 程序代码
struct In {
 double data;
 int other;
}s[100]
//按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种,
参考上面的例子写
int cmp( const void *a ,const void *b)
{
     return (*(In *)a).data > (*(In *)b).data ? 1 : -1;
}
qsort(s,100,sizeof(s[0]),cmp);

五、对结构体二级排序
程序代码 程序代码
struct In {
   int x; int y;
}s[100];
//按照x从小到大排序,当x相等时按照y从大到小排序
int cmp( const void *a , const void *b )
{
    struct In *c = (In *)a;
    struct In *d = (In *)b;
    if(c->x != d->x) return c->x - d->x;
    else return d->y - c->y;
}
qsort(s,100,sizeof(s[0]),cmp);

六、对字符串进行排序
程序代码 程序代码
struct In {
   int data; char str[100];
}s[100];
//按照结构体中字符串str的字典顺序排序
int cmp ( const void *a , const void *b )
{
    return strcmp( (*(In *)a)->str , (*(In *)b)->str );
}
qsort(s,100,sizeof(s[0]),cmp);

七、计算几何中求凸包的cmp
程序代码 程序代码
int cmp(const void *a,const void *b)
//重点cmp函数,把除了1点外的所有点,旋转角度排序
{
    struct point *c=(point *)a;
    struct point *d=(point *)b;
    if( calc(*c,*d,p[1]) < 0) return 1;
    else if( !calc(*c,*d,p[1])
   && dis(c->x,c->y,p[1].x,p[1].y) < dis(d->x,d->y,p[1].x,p[1].y))
   //如果在一条直线上,则把远的放在前面
   return 1; else return -1;
}
 
PS: 其中的qsort函数包含在<stdlib.h>的头文件里,strcmp包含在<string.h>的头文件里
posted @ 2008-11-15 21:32 hunter 阅读(270) | 评论 (0) | 编辑 收藏
 
ACM 1547 Clay Bully

听着Jay的《一路向北》,我一路水过来。。。今天真是啥水题都撞上了。。。

#include <iostream>
#include 
<vector>
#include 
<string>
#include 
<math.h>
#include 
<iomanip>
using namespace std;


int main()
{
    vector
<int> cubic;
    vector
<string> name;
    
int n,h,l,w;string s;
    cin
>>n;
    
while (n!=-1)
    
{
        cubic.clear();
        name.clear();
        
for (int i=0;i<n;i++)
        
{
            cin
>>h>>l>>w>>s;
            cubic.push_back(h
*l*w);
            name.push_back(s);
        }

        
int max=0,min=30000,maxn,minn;
        
for (int k=0;k<(int)cubic.size();k++)
        
{
            
if (cubic[k]>max)
            
{
                max
=cubic[k];
                maxn
=k;
            }

            
if (cubic[k]<min)
            
{
                min
=cubic[k];
                minn
=k;
            }

        }

        cout
<<name[maxn]<<" took clay from "<<name[minn]<<"."<<endl;
        cin
>>n;
    }

}
posted @ 2008-11-15 21:17 hunter 阅读(200) | 评论 (0) | 编辑 收藏
 
ACM 1528 Perfection
奇怪了,今天尽做些水题。。。啥也不说了,注意下1就行了,不算本身,和是0.。。
#include <iostream>
#include 
<vector>
#include 
<string>
#include 
<math.h>
#include 
<iomanip>
using namespace std;


int main()
{
    cout
<<"PERFECTION OUTPUT"<<endl;
    unsigned 
int n;
    cin
>>n;
    
while (n!=0)
    
{
        unsigned 
int sum=0;
        
if (n==1)
        
{
            sum
=0;
        }

        
else
        
{
            
for (int i=1;i<=n/2;i++)
           
{
            
if (n%i==0)
            
{
                sum
+=i;
            }

           }

        }

        
if (sum>n)
        
{
            cout
<<setw(5)<<n<<"  ABUNDANT"<<endl;
        }

        
else if (sum==n)
        
{
            cout
<<setw(5)<<n<<"  PERFECT"<<endl;
        }

        
else
        
{
            cout
<<setw(5)<<n<<"  DEFICIENT"<<endl;
        }

        cin
>>n;
    }

    cout
<<"END OF OUTPUT"<<endl;
}
posted @ 2008-11-15 20:58 hunter 阅读(295) | 评论 (0) | 编辑 收藏
 
ACM 1519 Digital Roots
很贱的一道题。。。我本来以为可以随便水的。。。结果还是WA了几次
输入的数居然可能是N千位。。。所以只能以字符串输入了

后面还看到个小技巧,如2位数ab,a+b=a*10+b-9*10=ab%9

#include <iostream>
#include 
<vector>
#include 
<string>
#include 
<math.h>
#include 
<iomanip>
using namespace std;

int sum;
void digsum(string& s)
{
    sum
=0;
    
for (size_t i=0;i<s.length();i++)
    
{
        sum
+=s[i]-'0';
    }

    sum
%=9;
    
if (sum==0)
    
{
        sum
=9;
    }

}

int main()
{
    vector
<int> result;
    
string s;
    
while (1)
    
{
        cin
>>s;
        
if (s=="0")
        
{break;
        }

        digsum(s);
        result.push_back(sum);
    }

    
for (size_t i=0;i<result.size();i++)
    
{
         cout
<<result[i]<<endl;
    }
    
}
posted @ 2008-11-15 16:07 hunter 阅读(277) | 评论 (0) | 编辑 收藏
 
仅列出标题
共8页: 1 2 3 4 5 6 7 8