08 2011 档案
摘要:这题给定的数一定能被N整除,最后要%1000003,那么我们就%1000003*N;这样我们就不要担心数据过大的问题;#include<stdio.h>#include<stdlib.h>int main(){ int T,n,x; __int64 num[40002]; scanf( "%d",&T ); for( int i=1; i<=T; i++ ) { scanf( "%d",&n ); __int64 ans=0,m=1000003; m*=n; num[0]=1; for( int j=1;..
阅读全文
摘要:该题要注意的就是每张单子A种类的总和不能大与600,同样B,C类也一样,刚开始我就错了这里,还有注意如果不是A,B,C类的不可以报销;该题就是要把浮点型变成整数这样才能用01背包,这里就只要乘以100就可以了。#include<stdio.h>#include<stdlib.h>#include<string.h>int f[5000024]={0};int DP( int num[],int count, int sum ){ memset( f,0,sizeof( f ) ); for(int i=0;i<count; i++) { for( in
阅读全文
摘要:#include<stdio.h>#include<stdlib.h>int Gcd( int a,int b ){ b==0?a:Gcd( b,a%b ); }int main(){ int n,m; while( scanf( "%d%d",&n,&m ),-1!=n&&-1!=m ) { if( 1==Gcd( n,m ) ) printf( "YES\n" ); else printf( "POOR Haha\n" ); } return 0; }该题与HD...
阅读全文
摘要:该题是是给出前3个数,要么是等差要么是等比,要你求第k个数,这个题关键是用到快速取幂;#include<stdio.h>#include<stdlib.h>long long getq( long long t,int k ){ if( k==1 ) return t; long long q = getq( t,k/2 ); if( k%2 ) { return ( q*q*t )%200907; } else return ( q*q )%200907; }int main(){ ...
阅读全文
摘要:该题就是HUD 1792与HDOJ 1222 Wolf and Rabbit的结合,先判断公约数是否大于1,如果大于就一定输出Inf,否则,就输出m*n-n-m;#include<stdio.h>long long Gcd( long long a, long long b ){ return b==0?a:Gcd( b,a%b ); }int main(){ long long n,m; while( scanf( "%I64d%I64d",&n,&m ),n||m ) { if( Gcd( n,m )==1 ) { ...
阅读全文
摘要:要判断给定的n(2<=n<=10^18)是不是squarefree number;因为给定的数最大达到10^18,所以直接暴力肯定是杯具的TLE;我们知道 N必为 3种之一: 素数,素数的平方,两个不同素数之积。10^18=10^6^3;那么我们求质数就只要求到10^6就可以,因为大于10^6就只能是平方次方,不可能是立方,因此可以用开方来判断;假如我们求质数小于10^6,那么可能这个数是一个数的立方,或者是一个质数的平方乘以一个数,但不能开方,但又不能被前面的质数相除,因此会造成不是squarefree number的假象。实现思路:1. 计算1000000以下 素数,存于 nu
阅读全文
摘要:刚开始试着用n*log(n)的方法去解,但细想一下这个方法是不行的,因为精度丢失好大,后来试着推里面的规律,这个规律就是n^n变成n^(n-1)再乘以n的所有位数之和,n^( n-2 )*((n的前所有位数之和)*n的前所有位数之和),以此类推。#include<stdio.h>#include<stdlib.h>#include<math.h>inline int SUM( int n ){ int sum=0,z=1; while( n/z ) { sum+=n%(z*10)/z; z*=10; } return...
阅读全文
摘要:看了这个题好久还是不知道怎么做,后来经过lvsi的指导,才把它给A了。m=n^n;两边同取对数,得到,log10(m)=n*log10(n);再得到,m=10^(n*log10(n));然后,对于10的整数次幂,第一位是1,所以,第一位数取决于n*log10(n)的小数部分;我们知道一个数x可以用10^(n +m)( n可以是小数,m是整数 )表示,那么10^n就是表示x/10^m之后的数及前面的数值。#include<stdio.h>#include<stdlib.h>#include<math.h>int main(){ int T; double N;
阅读全文
摘要:该题就从最高位取余,余数再乘以10就可以了;#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){ int n,m; char num[1024]; while( scanf( "%s%d",num,&m )!=EOF ) { int len=strlen( num ); int n=num[0]-'0',i=1; while( i<len ) { n=n*10+num[i]-'0'; n%=m; i++; } prin
阅读全文
摘要:该题是一道中国剩余定理题目,刚开始我就用了一下暴力的方法 (同时也优化了一下)一下子就超时了,后来看了一下这个题的解题报告才知道要用中国剩余定理,这也是我第一次用中国剩余定理解题。这个定理又叫孙子定理。就是给定几个数 虽然不互质 然后一个数取余他们又有相应的余数。那么这个问题的答案相差的一定是这些数的最小公倍数。首先我们求出最小公倍数K;然后在N%k+1到N%k+k这个范围内暴找一下有没有一个符合所有条件的数,我们把N分成一段段的,因为在每一段一定是没有或者只有一个的。为什么可以分成一段段的,我们知道中国剩余定理求的是最小的数,那么它的倍数同样是符合条件的;所以如果有的话 sum+=n/k;不
阅读全文
摘要:#include<stdio.h>#include<stdlib.h>int num[1024][300]={0};int main(){ int n; num[0][1]=1;num[1][1]=1;num[2][1]=2;num[3][1]=4; for( int i=4; i<=1000; i++ ) { for( int j=1;j<300; j++ ) { num[i][j]+=num[i-1][j]+num[i-2][j]+num[i-4][j]; num[i][j+1]=num[i][j]/10; num[i][j]%=10; } } whil
阅读全文
摘要:该题与HDU1086相似都是线段相交的问题,在这里就不解释线段相交了( 在HDU 1086You can Solve a Geometry Problem too已经解释了)不过我的代码还是注释一下:#include<stdio.h>#include<stdlib.h>#include<string.h>typedef struct T{ double x,y; }point; point start[200024],end[200024];inline double judge( point p1,point p2,point p )//判断点是否在直线的
阅读全文
摘要:求任意多边形的重心已知一多边形没有边相交,质量分布均匀。顺序给出多边形的顶点坐标,求其重心。分析:求多边形重心的题目大致有这么几种:1,质量集中在顶点上。n个顶点坐标为(xi,yi),质量为mi,则重心 X = ∑( xi×mi ) / ∑mi Y = ∑( yi×mi ) / ∑mi 特殊地,若每个点的质量相同,则 X = ∑xi / n Y = ∑yi / n2,质量分布均匀。这个题就是这一类型,算法和上面的不同。 特殊地,质量均匀的三角形重心: X = ( x0 + x1 + x2 ) / 3 Y = ( y0 + y1 + y2 ) / 33,质量分布不均匀。只能用
阅读全文
摘要:算法简单说明: 首先判断以两条线段为对角线的矩形是否相交,如果不相交两条线段肯定也不相交。(所谓以a1b2为对角钱的矩形就是以两边长为|a1.x – b2.x|和|a1.y – b2.y|以及a1b2为对角线的矩形)。如果相交的话,利用矢量叉乘判断两条线段是否相互跨越,如果相互跨越显然就相交,反之则不相交。算法不难,但是一些特殊情况需要考虑到,比如两条相段共线且在断点处相交。下面的代码经过测试了,应该没有bug,如果你真的发现了bug请告诉我:) /******************************************************** * * * 返回(P1-P0)*
阅读全文
摘要:x 、y、n都是正整数,并且 显然,x >= n , y >= n ,现在假设 y = n +k (k为正整数) ,那么带入公式,可以得出 x = (n*(n+k))/k = n*n/k + n; 由于x 是正整数,现在的关键问题就是要求出 n*n/ k 有多少组正整数的可能,显然,所要求的就是 n*n 因子的个数// 问题已经非常接近答案了,但是最后还有一个问题,n<= 10^9 , 那么n*n <= 10^18 ,对于一个这么大的数字怎样才能求出它因子的个数呢?命题1: 一个正整数 n 可以用素因子唯一表示为 p1^r1 * p2^r2 * ... pk^rk (其
阅读全文
摘要:#include<stdio.h>#include<stdlib.h>int main(){ double k,l,s,w; while( scanf( "%lf%lf%lf%lf",&k,&l,&s,&w ),k||l||s||w ) { if( l>=s )//当绳子大于桥的高度就只要判断势能转化成动能 { if(s>(100/19.62)) printf( "Killed by the impact.\n" ); else printf( "James Bond surv
阅读全文
摘要:该题只要注意前面几个精度就可以。#include<stdio.h>#include<stdlib.h>int main(){ int n=1,a[10]={1}; while( n<10 ) { a[n]=a[n-1]*n; n++; } printf( "n e\n" ); printf( "- -----------\n" ); printf( "0 1\n" ); printf( "1 2\n" ); printf( "2 2.5\n" ); n=3; dou
阅读全文
摘要:该题是一题找规律题,当n与m都是偶数或是倍数是就存在这样的洞,方法一:#include<stdio.h>#include<stdlib.h>int main(){ int n,m,N; scanf( "%d",&N ); for( int i=1; i<=N; i++ ) { scanf( "%d%d",&n,&m ); if( n==1 || m==1) printf( "NO\n" ); else { if( (n%2==0) && (m%2==0) ) pri
阅读全文
摘要:该题一直TLE,后来把qsort改成sort就过了,悲伤呀,该题用到DP中的分治法,先看看这题分治法的原理:<!--[if !supportLists]-->1、<!--[endif]-->问题综述最接近点对问题的提法是:给定平面上n个点,找其中的一对点,使得在n个点组成的所有点对中,该点对间的距离最小。实际情况下,最接近点对可能多于一对,为简单起见 ,我们只找其中的一对作为问题的解。有一个最直观的方法就是将每一点与其他n-1个点的距离算出,找出达到最小距离的两点即可。然而,这样做效率太低,我们想到用递归法来解决这个问题。2、 用递归法解决将所给的平面上n个点的集合S分
阅读全文
摘要:首先相信你已经看过《背包九讲》。对于每一次决策后,我们都能得到一组值:F[ i, j] I 表示进行了i次决策,j表示占用了j 的体积。最终获得了F[i,j]的收益。这么考虑的话,很显然,就能得到最优子结构的性质:如果最终能得到Fmax[ n, v ] ,那对于每一组i,j 必定 F[i,j]=Fmax[i,j]。因此,在遍历树的时候,如果两种决策有相同的i,j 那我们可以取出两者中的最大值,另外一种就被无情的抛弃了-_- 。这样,对于每一组的i,j 我们可以方便的按如下方程求出:F[i,j]=max( F[i-1,j] , f[i-1][j-volume[i]] + value[i] ) 按
阅读全文
摘要:该题分别给出面值为1,5,10,50,100的纸币数,求出,表示一个值的最少所需的纸币数,最多所需的纸币数。先贪心出最少的情况,怎样取得最小的,我们每次取币值最大,跟价钱比较,如果价钱大于币值,我们一定用币值大的,下面取得最小的,我们因该从刚满足我们价钱的最大的币值开始取,那么我们每次下去一定取得的数目是最大的,#include<stdio.h>#include<stdlib.h>#include<string.h>int minnumber( int a[], int num[], int price, int sum[] ){ int ans=0; fo
阅读全文
摘要:该题只是在完全背包基础之上加了一个条件,就是只能杀s个怪,那么我们就对每次记录每次在该忍耐点所杀的怪,如果所杀的怪大于所给的数目,那么我们就不更换经验值。怎样计算所剩的忍耐点,我们知道每一个忍耐点都是所杀怪所得到的经验值最大,那么我们只要对f进行遍历一遍,如果经验值大于等于所给的经验值,代表在该忍耐点已经可以获得了升级。#include<stdio.h>#include<stdlib.h>int DP( int add[],int reduce[], int n, int m, int k,int s ){ int f[124]={0},hash[124]={0},;
阅读全文
摘要:该题WA了几次,一直找不出错误,后来经过livs的指导,我们先拿出5元,这5元一定是买价钱最贵的菜,这样才能保证剩余的钱最少,那么我们还要做一件事就是选取最贵的菜,这两件事处理好了,就是一件简单的01背包。#include<stdio.h>#include<stdlib.h>int ZeroOnePack( int price[],int money,int n ,int pos,int max){ int f[1024]={0}; for( int i=1; i<=n; i++ ) { if( i!=pos ) for( int j=money-5 ; j>
阅读全文
摘要:该题搞了一个晚上才A了它,刚开始一直不能出正确结果,总认为是我的二分哪里错了,修改了几个小时,还重敲了,后来才发现是矩阵建反了,该题最重要的是建立矩阵,如果矩阵建立好了,就万事顺利了,怎样建立这个矩阵了,我们来讨论一下(n>10),f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);我们来看个图:、矩阵A 矩阵B0 1 0 0 0 0 0 0 0 0 f0 f10 0 1 0 0 0 0 0 0 0 f1 f20 0 0 1 0 0 0 0 0 0 f2 f30 0 0 0 1 0 0 0 0 0 * f3
阅读全文
摘要:该题是母函数的变种,也是一种多重背包问题,由于写了几篇这样的,所以就不重累述了,如果不懂可以看一下背包九讲;#include<stdio.h>#include<stdlib.h>int CompletePack( int f[],int val,int money ,int sum)//完全背包{ for( int i=val; i<=money;i++ ) { if( i>=val&&f[ i-val ]+val>f[i] ) { f[i]=f[i-val]+val; if( f[ i ]==i )//如果相等,则代表有这种情况 {
阅读全文
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=2191#include<stdio.h>#include<stdlib.h>void CompletePack( int price,int f[],int money,int weight )//完全背包{ for( int i=price; i<=money; i++ ) { if( f[ i-price ]+weight>f[i] ) { f[i]=f[i-price] + weight; } } }void ZeroOnePack( int price,int nu
阅读全文
摘要:今天学了一下多重背包,这是我A的第一个题,刚开始用用比较暴力的,没优化的多重背包就TLE了。代码如下:#include<stdio.h>#include<stdlib.h>int DP( int val[], int N ){ int f[100024]={0}; for( int i=1;i<=6; i++ )//取不同的元素 { for( int j=1; j<=val[i]; j++ )//取元素的个数 { for( int k=N; k>=0; k-- ) { int t=j*i; if( t<=k&&f[ k-t ]+t
阅读全文
摘要:该题利用了我们的逆向思维,同时要注意该题他的质量是一定的,也就是说背包一定要是满的,刚开始对于这类背包我们令初始值是负无穷,而这题则相反,令初始值是正无穷,每次区最小的数,同时要注意f[j-weight[i]]!=inf应为一相等就与背包一定要满的条件相矛盾;#include<stdio.h>#include<stdlib.h>const int inf=0x7fffffff;int DP( int weight[],int val[],int N,int vol ){ int f[50024]={0}; for( int i=1; i<=vol; i++ ) f
阅读全文
摘要:该题是一道拓扑排序,拓扑排序就是每次寻找入度为0的节点,如果没有入度为0的节点但节点并没有完全找出,则该排名失败了;由于没有图,不好解释,建议你去看一下数据结构,我这里实现的是链表的方法:#include<stdio.h>#include<stdlib.h>#include<string.h>typedef struct AOE{ int n; struct AOE *next;}AOE;struct T{ int n,flag; AOE *next;}VEX[524]; void build( int x, int y) //建立表{ AOE *p; if
阅读全文
摘要:这是一道赤裸裸的简单的完全背包,在HDU 2602中我说过在01背包优化的算法中提醒要注意v V--0,而不是0--V ,其实反过来就是完全背包;这个算法使用一维数组,先看伪代码:for i=1..N forv=0..Vf[v]=max{f[v],f[v-cost]+weight}你会发现,这个伪代码与P01的伪代码只有v的循环次序不同而已。这里还是要啰嗦一下,#include<stdio.h>#include<stdlib.h>int a[3]={ 150,200,350 };int DP( int money ){ int f[10024]={ 0 }; for(
阅读全文
摘要:由于受定势思维的的影响,一直没想到反过来去求他没有被录上的情况,其实44.0%是这样来的,就是1-((1-0.2)*(1.0.3)),(1-0.2)*(1.0.3)是最小的被录取的情况,同时该题是一道01背包。#include<stdio.h>#include<stdlib.h>float DP( int money[],float a[], int N ,int M){ float f[10024]; for( int i=0; i<=M; i++ ) f[i]=1; for( int i=1; i<=N; i++ ) { for( int j=M; j&
阅读全文
摘要:该题是一道背包题,并且是一个0,1背包,这种背包特点是:每种物品仅有一件,可以选择放或不放。用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价
阅读全文
摘要:刚学了一下KMP就去做该题,一提交就是TLE,后来才知道是AC自动机,对于KMP我就不诠释了,AC自动机就是next函数的思想,这里就是构建tire树与fail指针,如果你对KMP不了解,那么你就先去了解一下KMP吧。如果你对KMP算法和了解的话,应该知道KMP算法中的next函数(shift函数或者fail函数)是干什么用的。KMP中我们用两个指针i和j分别表示,A[i-j+ 1..i]与B[1..j]完全相等。也就是说,i是不断增加的,随着i的增加j相应地变化,且j满足以A[i]结尾的长度为j的字符串正好匹配B串的前 j个字符,当A[i+1]≠B[j+1],KMP的策略是调整j的位置(减小
阅读全文
摘要:http://openoj.awaysoft.com/JudgeOnline/problem.php?id=1567该题是一道纯模拟题,这道题比较好的解法就是用二维栈,因为每次被折的栈里面的元素都要反过来,这与栈的特性FILO是一样的,可以用栈来就行模拟。#include<stdio.h>#include<stdlib.h>typedef struct s{ int x,y; }POS;struct tt{ POS link[450]; int top; }map[24][24];int top,down,right,left;void T_ZHE(){ for( in
阅读全文
摘要:素数筛选法一直是数论中的重点,你找到的规律越多你的筛选就越快。先让我们 看一个算法:#include<stdio.h>#include<math.h>#define MAX_P 500int nList[MAX_P] = {0};void Calc(){ int n,p,t,sq=(int)sqrt(MAX_P*2+1); for (n=3;n<=sq;n+=2) { if (nList[n>>1]) continue; for (t=n*n;t<=MAX_P<<1;t+=n<<1) //筛选循环 nList[t>&
阅读全文
摘要:Description我们知道,任何一个大于1的数,都可以写成多个素数的乘积,我们把这些素数叫做这个数的素因子。Input第一行为测试数据的组数N,以下N行,每行一个数字k(1<k<2^24)Output输出N行,每行两个数字,一个是k的最大素因子,第二个是k的素因子的个数。Sample Input3 10 25 120Sample Output52 5 1 5 3代码:#include<stdio.h>#include<stdlib.h>#include<math.h>bool a[2100]={0};int num[600];int main
阅读全文
摘要:这个题是一个几何题,主要考虑精度问题,为了减少精度的损失,尽量少用除法,该题如果先算出斜率k,那么后面就会精度损失;该题最好用向量解比较好;该题要注意两直线垂直的情况;poj上面的测试数据太弱了;#include<stdio.h>#include<stdlib.h>int main( ){ double A1,B1,A2,B2,X1,Y1,X2,Y2; double PX,PY,QX,QY; int n; scanf("%d",&n); printf("INTERSECTING LINES OUTPUT\n"); for(
阅读全文
摘要:该题我也WA了几次,后来才知道该题用了错排的知识,在看代码之前,我们先证明一下错排。有个牵手游戏规则如下:有标号 1.的女生与标号1,2,3,4......n-1,n.的男生.我们规定标号相同的男生与女生不能牵手。同时规定错排个数为M(1),M(2),M(3)。。。M(n-1),M(n),我们假设1号女生先开始牵手,那么有n-1种选法,我们假设2号女生牵手1和不牵1男生手的两种情况,假设2一定牵手1,那么还有编号3,4......n-1,n的男女生,则有(n-1)*M(n-2)种情况;另一种情况2一定不牵1的手,那么1号男生就等价于2号男生因为1号男生一定不能牵2号女生的手,相当于还有编号2,
阅读全文

浙公网安备 33010602011771号