|
常用链接
留言簿(4)
随笔分类
随笔档案
搜索
最新评论

阅读排行榜
评论排行榜
Powered by: 博客园
模板提供:沪江博客
|
|
|
|
|
发新文章 |
|
|
给定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");

}
}
妈的,没见过那么恶心的题目。。。 首先题目就错了,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");
}



}
}
传说中的动态规划。。。 注意题目的优先计算顺序。先是考虑是否会小于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]);
}
}
}
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
摘要: 今天总算是碰到一道复杂题了。。。(我BT了?)弄死我了,主要是排除重复情况,我想不通,最后参考了前人的代码,修改后AC了。。。思路:通过递归,得出可能存在的解法,并记录,查找原记录,若存在相同则取消记录
#include <iostream>#include <vector>#include <string>#include&nb... 阅读全文
<本文中排序都是采用的从小到大排序> 一、对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>的头文件里
|
|