算法实战:给定一个带通配符问号的数W,问号可以代表任意一个一位数字。 再给定一个整数X,和W具有同样的长度。 问有多少个整数符合W的形式并且比X大?
来源:互联网 发布:网络约车平台 编辑:程序博客网 时间:2024/05/18 00:55
如题:
给定一个带通配符问号的数W,问号可以代表任意一个一位数字。
再给定一个整数X,和W具有同样的长度。问有多少个整数符合W的形式并且比X大?
输入格式
多组数据,每组数据两行,第一行是W,第二行是X,它们长度相同。在[1..10]之间.
输出格式
每行一个整数表示结果。
答题说明
输入样例
36?1?8
236428
8?3
910
?
5
输出样例
100
0
4
分析如下:
先用穷举法来分析几种可能情况
1.
36?1?8
236428
如果W第一个通配符之前的数字大于X,则通通配符可以是任意数字,因此W比X大的个数就是10的n次方(通配符个数n)
2.
8?3
910
如果W第一个通配符之前的数字小于x,则W不可能比X大,结果为0
3.
2?
25
如果W第一个通配符之前的数字等于x,这时,只有W的通配符比X相应位置的数字大的情况,才有可能使w比X大,因此通配符前面的数字不起任何作用,
我们可以把它简化为
?
5
此时可以得到结果为4
分析完了第一个通配符我们来分析第二个通配符,这时我们发现,只有第一个通配符前面没有数字或数字和x相等的情况下,我们才需要考虑第二个通配符。
并且情况很相似,只有第一个通配符和x相同位置中的数字相等的情况,我们才需要对第二个通配符进行分析,
否则,跟上面的情况类似,
如果第一个通配符大于x中的数字,则W比X大的个数就是10的n-1次方(通配符个数n)
如果第一个通配符小于x中的数字,则W比X大的个数就是0
以此类推,就可以得出W比X大总个数
c#示例代码如下:
/// <summary> /// 使用算法推算w大于x的个数 /// </summary> /// <param name="string_W"></param> /// <param name="string_X"></param> /// <returns></returns> private int getNum(string string_W, string string_X) { if (int.Parse(string_W.Replace('?', '9')) <= int.Parse(string_X)) { return 0; } int firstCharIndex = -1;//第一个通配符的索引 int secondCharIndex = -1;//第二个通配符的索引 int value_x = 0;////字符串string_X中在第一个通配符相应位置的数字的值 int charCount = 0;//通配符数量 //找到第一个通配符的索引和第二个通配符的索引 for (int i = 0; i < string_W.Length; i++) { if (string_W[i] == '?') { charCount++; if (firstCharIndex == -1) { value_x = int.Parse(string_X[i].ToString()); firstCharIndex = i; continue; } if (firstCharIndex != -1 && secondCharIndex == -1) { secondCharIndex = i; } } } //第一个通配符前面有数字,并且与x不相等的情况 if (firstCharIndex > 0) { int formerValue_W = int.Parse(string_W.Substring(0, firstCharIndex)); int formerValue_X = int.Parse(string_X.Substring(0, firstCharIndex)); if (formerValue_W > formerValue_X) { //如果之前的数据W>X,则=通配符的个数n 10的n次方 return (int)Math.Pow(10, charCount); } else if (formerValue_W < formerValue_X) { return 0; } } //如果第一个通配符之前的数相等或没有数字,判断通配符和X字符的大小情况 if (charCount > 1) { //递归计算出结果 第一个通配符大于x的情况+等于x时进行递归推算 return (9 - value_x) * (int)Math.Pow(10, charCount - 1) + getNum(string_W.Substring(firstCharIndex + 1), string_X.Substring(firstCharIndex + 1)); } else { //只有一个通配符,判断当通配符与x相同位置的整数相同时,w和x的大小 int W = int.Parse(string_W.Replace('?', string_X[firstCharIndex])); int X = int.Parse(string_X); if (W > X) { return (9 - value_x) + 1; } else { return (9 - value_x); } } } /// <summary> /// 使用常规逻辑遍历计算w大于x的个数 /// </summary> /// <param name="string_W"></param> /// <param name="string_X"></param> /// <returns></returns> private int CalNum(string string_W, string string_X) { int value_x = int.Parse(string_X); string[] parms_w = string_W.Split('?'); string[] charDic = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "l", "m" };//最多10个 //字符字典,用于依次替换string_W中的通配符,以方便递归方法中的遍历 string_W = ""; for (int i = 0; i < parms_w.Length; i++) { string_W += parms_w[i] + charDic[i]; } string_W = string_W.Substring (0,string_W .Length -1); int charCount = parms_w.Length - 1; return CalNum_sub(string_W, value_x, charDic, charCount); ; } /// <summary> /// CalNum方法中用到的递归计算 /// </summary> /// <param name="string_W"></param> /// <param name="value_x"></param> /// <param name="charDic"></param> /// <param name="charCount"></param> /// <returns></returns> private int CalNum_sub(string string_W, int value_x, string[] charDic, int charCount) { int total = 0; for (int k = 0; k < 10; k++) { string temp = string_W.Replace(charDic[charCount - 1], k.ToString()); if (charCount > 1) { total += CalNum_sub(temp, value_x, charDic, charCount - 1); } else { if (int.Parse(temp) > value_x) { total++; } } } return total; } /// <summary> /// 测试方法 /// </summary> /// <param name="string_W"></param> /// <param name="string_X"></param> /// <returns></returns> private string testNum(string string_W, string string_X) { Stopwatch watch = new Stopwatch(); watch.Start(); int v1 = CalNum(string_W, string_X); watch.Stop(); string t1 = watch.ElapsedTicks.ToString(); watch.Reset(); watch.Start(); int v2 = getNum(string_W, string_X); watch.Stop(); string t2 = watch.ElapsedTicks.ToString(); return (v1 + "--" + v2 + "\r\n" + t1 + "--" + t2).ToString(); }
0 0
- 给定一个带通配符问号的数W,问号可以代表任意一个一位数字。 再给定一个整数X,和W具有同样的长度。 问有多少个整数符合W的形式并且比X大?
- 给定一个带通配符问号的数W,问号可以代表任意数字。 再给定一个整数X,和W具有同样的长度。 问有多少个整数符合W的形式并且比X大?
- 算法实战:给定一个带通配符问号的数W,问号可以代表任意一个一位数字。 再给定一个整数X,和W具有同样的长度。 问有多少个整数符合W的形式并且比X大?
- 给定任意一个整数,找出比当前这个数大的最小的10个素数之和。
- 给定一个整数数组,在该数组中,寻找三个数,分别代表三角形三条边的长度,问,可以寻找到多少组这样的三个数来组成三角形?
- [LintCode 382]给定一个整数数组,在该数组中,寻找三个数,分别代表三角形三条边的长度,问,可以寻找到多少组这样的三个数来组成三角形?
- 今天大家做的一个比赛题:有6个文件,每个文件里大约200w整数,每行一个找出所有文件里最大的一个数字
- PKU1401:给定一个整数N,那么N的阶乘N!末尾有多少个0。
- 给定一个整数N,那么N的阶乘N!末尾有多少个0
- 给定一个整数N,那么N的阶乘N!末尾有多少个0呢
- 给定一个整数N,那么N的阶乘N!末尾有多少个0呢?
- 给定一个整数N,求它的阶乘末尾有多少个0呢?
- 给定一个整数N,求N的阶乘N!末尾有多少个0?
- 给定一个整数N,那么N的阶乘N!末尾有多少个0呢?
- 给定一个整数N,那么N的阶乘N!末尾有多少个0
- 给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数
- 给定一个任意长度的java数组,求数组内的数能组合出来的最大整数
- 给定一个整数,分别打印出每一位数字,然后每行都省略输出上一行的第一个数字
- Servlet笔记 (八) i18nFilter国际化
- Servlet笔记 (九) 过滤器及文件上传下载
- 微信公众账号开发模式2
- 九度题目1172:哈夫曼树
- ACM-计算几何之受到攻击——hrbust1291
- 算法实战:给定一个带通配符问号的数W,问号可以代表任意一个一位数字。 再给定一个整数X,和W具有同样的长度。 问有多少个整数符合W的形式并且比X大?
- 程序阅读:简单C++学生信息管理系统
- Servlet笔记(十) servlet监听器 JavaMail
- 范式编程之栈的实现
- iptables规则绑定在端口而不是拦截在协议栈
- 触发Full GC执行的情况
- [android secure]android应用安全——代码安全(android代码混淆)
- 成员对象
- 面试经典(20)--数对之差的最大值