UVa 153 - Permalex

题目:给你一个字符串,判断他是这些字符组成的全排列中按字典序排序的第几位。

分析:组合数学。康托展开,枚举长度求和即可。

首先,考虑非重集,从前向后扫描,每一位找到前面相同本位小于对应值得串个数;

例如:f(cba)= 2*2!+ 1*1!= 5,对应第6个串;

(c**对应a、b开头的比他小,cb*对应ca开头的比他)

然后,考虑重集,对应位置取相同的元素相同,剩余的元素要去掉相同的全排列;

例如:f(cabaa)= (4!/3!+ 4!/2!)+ (0) + (2!/1!)+(0) = 18,对应第19个串;

(c****对应b开头为4!/3!(aaa)、a开头为4!/2!(aa),cab**对应caa开头为2!/1!(a))

注意,这里因为30!超过了long long,使用数组存所有的因数,利用gcd约分就得到int范围内的值了。

说明:还没有到600题╮(╯▽╰)╭。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

int gcd(int a, int b)
{
	return a%b?gcd(b, a%b):b;
}

int main()
{
	int  letter[128];
	int  u[200],d[200];
	char buf[32];
	while (~scanf("%s",buf)) {
		if (!strcmp("#", buf))
			break;
		memset(letter, 0, sizeof(letter));
		for (int i = 0; buf[i]; ++ i)
			letter[buf[i]] ++;

		int len = strlen(buf),count = 1;
		for (int i = 0; i < len; ++ i) {
			int d_count = 0,u_count = 0;
			for (int j = 'a'; j <= 'z'; ++ j)
				for (int k = 2; k <= letter[j]; ++ k)
					d[d_count ++] = k;
			for (int k = 2; k <= len-1-i; ++ k)
				u[u_count ++] = k;

			for (int j = 'a'; j < buf[i]; ++ j) {
				if (letter[j]) {
					int g = 1,value = 1;

					u[u_count] = letter[j];
					for (int p = 0; p <= u_count; ++ p)
					for (int q = 0; q < d_count; ++ q) {
						g = gcd(u[p], d[q]);
						u[p] /= g;
						d[q] /= g;
					}
					for (int p = 0; p <= u_count; ++ p)
						value *= u[p];
					count += value;
				}
			}
			letter[buf[i]] --;
		}

		printf("%10d\n",count);
	}
    return 0;
}
时间: 2024-10-07 18:57:50

UVa 153 - Permalex的相关文章

[题解]UVa 12661 Funny Car Racing - spfa

很简单的一道最短路问题.分情况处理赛道的打开和关闭. Code 1 /** 2 * UVa 3 * Problem#12661 4 * Accepted 5 * Time:50ms 6 */ 7 #include<iostream> 8 #include<fstream> 9 #include<sstream> 10 #include<cstdio> 11 #include<cstdlib> 12 #include<cstring>

[题解]UVa 11082 Matrix Decompressing

开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且题目中然而并没有什么要求,所以说可以考虑思考一下这道题有木有什么"套路"之类的通法) 比如说有这么一组数据 原矩阵 1 2 3 4 7 8 9 5 6 输入 3 3 6 25 45 14 28 45 然后将每一行的和写在每一列对应的行上(很明显有问题) 6 0 0 19 0 0 20 0

UVA 658 It&#39;s not a Bug, it&#39;s a Feature! (单源最短路,dijkstra+优先队列,变形,经典)

题意:有n个bug,有m个补丁,每个补丁有一定的要求(比如某个bug必须存在,某个必须不存在,某些无所谓等等),打完出来后bug还可能变多了呢.但是打补丁是需要时间的,每个补丁耗时不同,那么问题来了:要打多久才能无bug?(同1补丁可重复打) 分析: n<=20,那么用位来表示bug的话有220=100万多一点.不用建图了,图实在太大了,用位图又不好玩.那么直接用隐式图搜索(在任意点,只要满足转移条件,任何状态都能转). 但是有没有可能每个状态都要搜1次啊?那可能是100万*100万啊,这样出题

[题解]uva 1658 Admiral

vjudge传送门[here] 题目大意:给一个有(3≤v≤1000)个点e(3≤e≤10000)条边的有向加权图,求1~v的两条不相交(除了起点和终点外没有公共点)的路径,使权值和最小. 正解是吧2到v-1的每个点拆成两个点,中间连一条容量为1,费用为0的边,然后求1到v的流量为2的最小费用流就行了. Code 1 /** 2 * Uva 3 * Problem#1658 4 * Accepted 5 */ 6 #include<iostream> 7 #include<cstdio&

UVA 11324 The Largest Clique (强连通分量缩点,图DP)

题目: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=show_problem&problem=2299 题意: 给你一个有向图,求一个点集合的最大大小,使得此点集合中对于任意点对(u,v),有从u到v或者从v到u的边 方法: 先找强连通分量缩点,每个强连通分量显然满足条件,然后在缩点后的图中找到一条权值最大的路径,权值为此路径的点权之和,点权为这个

UVA 1146 Now or later

二分时间+2sat 边加多了....RE了好久...... Now or later Time Limit: 9000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description As you must have experienced, instead of landing immediately, an aircraft sometimes waits

uva 704

自己之前的不见了.. 这题是双向广搜即可过.. 1 // Colour Hash (色彩缤纷游戏) 2 // PC/UVa IDs: 110807/704, Popularity: B, Success rate: average Level: 3 3 // Verdict: Accepted 4 // Submission Date: 2011-08-28 5 // UVa Run Time: 0.048s 6 // 7 // 版权所有(C)2011,邱秋.metaphysis # yeah

UVA 11983 Weird Advertisement(线段树求矩形并的面积)

UVA 11983 题目大意是说给你N个矩形,让你求被覆盖k次以上的点的总个数(x,y<1e9) 首先这个题有一个转化,吧每个矩形的x2,y2+1这样就转化为了求N个矩形被覆盖k次以上的区域的面积 由于坐标很大,首先考虑的就是将坐标离散化,然后建立线段树tree[][K],表示x的某个区间被覆盖了K次(大于K次算K次)的实际长度,在计算时把矩形转化为一系列横线段(就是说将一个矩形拆开为两条线段,下面的标记为1,上面的标记为-1(这里的标记很有技巧)),然后将这些线段按照y值的从小到达排序(y值相

Fast Matrix Operations(UVA)11992

UVA 11992 - Fast Matrix Operations 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素add上val: 2 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素set为val: 3 x1 y1 x2 y2 val 表示输