zoukankan      html  css  js  c++  java
  • POJ1850&&1019&&1942

    这三道题都水的难以想象,所以就放在一起写

    1850

    题目大意:有一种一种序列排列方式(如同题目中给出的例子),然后给你一个序列,问你这个序列的排名

    首先我们先判断无解的情况,这个就很简单了。

    由于题目给出的排列方式我们知道:若这个序列不满足一直上升的情况,那么一定无解

    很好理解吧,然后我们进一步分析:在有解的情况下,如果构成这种序列的所有字符都确定了,那么它们的顺序都唯一确定了

    然后我们可以求出所有长度小于这个序列的序列的总排名,即ΣC[26][i] (1<=i<len)

    然后对于所有长度和它一样的序列,枚举每一位上可以使用的比他小的字符,然后组合数退一下即可

    具体看代码,这个很好理解

    CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    char s[15];
    int C[30][30],len,ans=1,last;
    inline void init(void)
    {
    	for (register int i=1;i<=26;++i)
    	{
    		C[i][0]=1; C[i][i]=1;
    		for (register int j=1;j<i;++j)
    		C[i][j]=C[i-1][j]+C[i-1][j-1];
    	}
    }
    int main()
    {
    	register int i,j;
    	init();
    	scanf("%s",s+1); len=strlen(s+1);
    	for (i=2;i<=len;++i)
    	if (s[i]<=s[i-1]) { puts("0"); return 0; }
    	for (i=1;i<len;++i)
    	ans+=C[26][i]; last=1;
    	for (i=1;i<=len;++i)
    	{
    		int now=s[i]-'a'+1;
    		for (j=last;j<now;++j)
    		ans+=C[26-j][len-i];
    		last=now+1;
    	}
    	printf("%d",ans);
    	return 0;
    }
    

    1019

    这道题我愣是没看出来和组合数的关系

    题意也是给你一串序列(直接看题目),这个规律明显。让你求它的第i项是多少

    裸的枚举题。我们只需要先找出所以在它之前的完整结束的序列的数字总数,然后让n减去即可得出在当前这个序列中的第几项

    然后我们稍作分析:

    • 一位数0~9,共9个,占用数字9*1=9个

    • 两位数10~99,共90个,占用数字90*2=180个

    • 三位数100~999,共900个占用数字900*3=2700个

    • ......

    这个规律就很显然了吧,这样我们就可以直接得出它是哪个数的第几位,最后输出即可

    具体看CODE

    #include<cstdio>
    using namespace std;
    typedef long long LL;
    LL t,sum,n,num,last;
    inline LL pow_10(LL k)
    {
    	LL tot=1;
    	for (register LL i=1;i<=k;++i)
    	tot*=10;
    	return tot;
    }
    inline LL get(LL x,LL w)
    {
    	while (w--) x/=10;
    	return x%10;
    }
    inline LL len(LL x)
    {
    	int cnt=0;
    	while (x) ++cnt,x/=10;
    	return cnt;
    }
    int main()
    {
    	register LL i; scanf("%lld",&t);
    	while (t--)
    	{
    		scanf("%lld",&n);
    		for (i=1,sum=0,last=0;;++i)
    		{
    			last+=len(i);
    			if (sum+last>=n) break; sum+=last;
    		}
    		n-=sum; sum=0;
    		for (i=1;;++i)
    		{
    			if (sum+pow_10(i-1)*9*i>=n) { num=i; break; } sum+=pow_10(i-1)*9*i;
    		} n-=sum;
    		if (!num) { printf("%lld
    ",n); continue; }
    		if (n%num) printf("%lld
    ",get(pow_10(num-1)+n/num,num-n%num)); else printf("%lld
    ",get(pow_10(num-1)+n/num-1,0));
    	}
    	return 0;
    }
    

    1942

    这道题是真心水,题意就是从一个方格图的左下角走到右上角的方案总数(沿着边走)

    这题用递推法绝壁或超时,但是求方案数的话我们可以直接考虑这么一种想法:

    首先我们观察到向右永远走n步,向上永远走m步,总步数永远是n+m

    然后不同的方案本质其实就是它们的排列组合不同

    然后稍加推导就是从n+m个地方里面选取n个填上数的方案数

    即要求的就是:C(n+m,n)||C(n+m,m)

    但是这里用阶乘的会爆精度,递推法又会超时,不过由于题目说明答案一定在unsighed int 范围内,所以我们只能用约分法

    首先对于,C(n+m,n)有:

    然后我们将上下都消去n!,则:

    然后就可以得到:

    ans=ans*(i+n)/i(1<=i<=m)
    

    不停除下去即可,这里我们总是选取n,m中小的一个来进行循环可以快一点

    CODE

    #include<cstdio>
    #include<cmath>
    using namespace std;
    long long n,m;
    inline char tc(void)
    {
    	static char fl[100000],*A=fl,*B=fl;
    	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(long long &x)
    {
    	x=0; char ch=tc();
    	while (ch<'0'||ch>'9') ch=tc();
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
    }
    inline void write(long long x)
    {
    	if (x/10) write(x/10);
    	putchar(x%10+'0');
    }
    inline void swap(long long &a,long long &b)
    {
    	long long t=a; a=b; b=t;
    }
    inline long long calc(long long n,long long m)
    {
    	long long tot=1.0;
    	for (register long long i=1;i<=n;++i)
    	tot=tot*(m+i)/i;
    	return tot;
    }
    int main()
    {
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	for (;;)
    	{
    		read(n); read(m);
    		if (!n&&!m) break;
    		if (n>m) swap(n,m);
    		write(calc(n,m)); putchar('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    Microsoft Exchange Mail Flow Rule
    Microsoft Exchange Inactive mailbox
    Microsoft Exchange In-Place Hold and Litigation Hold
    Microsoft Exchange eDiscovery
    Microsoft Exchange Retention Policy
    JavaScript Array 操作
    CSS选择器优先级
    CSS实现垂直居中
    watch和computed和methods区别是什么?
    什么是async和await? 怎么捕获异常?
  • 原文地址:https://www.cnblogs.com/cjjsb/p/9082447.html
Copyright © 2011-2022 走看看