Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4561724
  • 博文数量: 1214
  • 博客积分: 13195
  • 博客等级: 上将
  • 技术积分: 9105
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
个人简介

C++,python,热爱算法和机器学习

文章分类

全部博文(1214)

文章存档

2021年(13)

2020年(49)

2019年(14)

2018年(27)

2017年(69)

2016年(100)

2015年(106)

2014年(240)

2013年(5)

2012年(193)

2011年(155)

2010年(93)

2009年(62)

2008年(51)

2007年(37)

分类: Python/Ruby

2012-05-04 17:49:04

  A,B 是位数相同的两个数,给定A,B 求满足 An < mB 的(n, m) 对的数目。
  n 左移的若干位数,补到右边得到m ,比如: 1234 可以得到的 2341,3412,4123。
--------------------------------------------------------------------------------

  题目描述相当简单,存在一个特例,1212 可以得到 2121,1212,2121。所以存在重复的(n, m)对,google给出的解决思路是左移时,如果得到原数就跳出循环。而这个聪明的break,我看的20个参赛者只有一个想到。还看到一些用移位做的代码,读不明白。

  简单的移位只要2个for循环就搞定了:

点击(此处)折叠或打开

  1. def control(content):
  2.     result = []
  3.     for count, line in enumerate(content):
  4.         A, B = line.rstrip('\n').split()
  5.         A, B = int(A), int(B)
  6.         num = 0
  7.         for i in range(A, B):
  8.             if i <= 10: continue
  9.             n = str(i)
  10.             for j in range(1, len(n)):
  11.                 if n[j] == '0': continue
  12.                 m = int(n[j:] + n[:j])
  13.                 if m == i: break
  14.                 if m > i and m <= B:
  15.                     num += 1
  16.         result.append('Case #' + str(count+1) + ': ' + str(num) + '\n') # (1212, 2121) show twice

  17.     return result
 
Tips
:在跑大数据时,python3 无法在8分钟内跑完,把range改成xrange用python2.7跑,6分多就可以跑完。这就是传说中的Python3效率不及Python2。

PS:我看了别人的程序,感觉这个比赛的美妙之处就在于一万个人有一万种程序、一万种思路,但是解决一个问题的方法也就那么几种。看到有日本人用D语言开发的,大部分人是C++,还有一人写的我没看懂。大致思路是先算一遍限定范围内所有的数,每次取一段数复制出来做计算。要是有程序能实现计算一部分数,下次到这一段就不用计算,那才叫牛。
下面我展示一些参赛者的程序。
0. Google给出的方案,相当的清晰,看着相当的爽快。

点击(此处)折叠或打开

  1. int solve(int A, int B) {
  2.     int power = 1, temp = A;
  3.     while (temp >= 10) {
  4.         power *= 10;
  5.         temp /= 10;
  6.     }
  7.     int result = 0;
  8.     for (int n = A; n <= B; ++n) {
  9.         temp = n;
  10.         while (true) {
  11.             temp = (temp / 10) + ((temp % 10) * power);
  12.             if (temp == n)
  13.                 break;
  14.             if (temp > n && temp <= B)
  15.                 result++;
  16.         }
  17.     }
  18.     return result;
  19. }

 
1.不错的思路,但是test的数组做的不是很好,也许作者lxx为了快。

点击(此处)折叠或打开

  1. int tens[] = {1,10,100,1000,10000,100000,1000000,10000000};

  2. int main() {
  3.   int tc; scanf("%d", &tc);
  4.   for(int tci = 0; tci < tc; tci++) {
  5.     int a,b; scanf("%d%d", &a, &b);
  6.     int d; for(d=0;tens[d]<=a;d++);
  7.     int cnt = 0;
  8.     for(int x = a; x < b; x++) {
  9.       int vals[10];
  10.       vals[0]=0;
  11.       for(int i = 1; i < d; i++) {
  12.         vals[i] = x/tens[i]+x%tens[i]*tens[d-i];
  13.       }
  14.       sort(vals, vals+d);
  15.       for(int i = 1; i < d; i++) {
  16.         if(x < vals[i] && vals[i-1]<vals[i] && vals[i] <= b) cnt++;
  17.       }
  18.     }
  19.     printf("Case #%d: %d\n", tci+1, cnt);
  20.   }
  21.   return 0;
  22. }

2.getPower10() 函数很好的解决上面的test不够优雅的问题。不过knownNumber 有点耗费空间,currentId也感觉会不会溢有出的可能。

点击(此处)折叠或打开

  1. const int MAX_X = 10000005;
  2. int knownNumber[MAX_X] = {0};
  3. int currentId = 0;

  4. int getPow10(int x) {
  5.     int pow10 = 1;
  6.     for (pow10 = 1; x >= pow10; pow10 *= 10) {}
  7.     return pow10;
  8. }

  9. int main() {
  10.     int nCases;

  11.     scanf("%d", &nCases);
  12.     for (int iCase = 1; iCase <= nCases; iCase++) {
  13.         int xMin, xMax;
  14.         scanf("%d%d", &xMin, &xMax);
  15.         int pow10 = getPow10(xMin);
  16.         assert(pow10 == getPow10(xMax));
  17.         int solution = 0;
  18.         for (int x = xMin; x <= xMax; x++) {
  19.             currentId++;
  20.             int rotX = x;
  21.             while (knownNumber[rotX] < currentId) {
  22.                 knownNumber[rotX] = currentId;
  23.                 solution += (x < rotX && rotX <= xMax);
  24.                 rotX = (rotX + (rotX % 10) * pow10) / 10;
  25.             }
  26.         }
  27.         printf("Case #%i: %i\n", iCase, solution);
  28.     }
  29.     return 0;
  30. }
3. SnapDragon的超级简练的代码:

点击(此处)折叠或打开

  1. #include <iostream>
  2. using namespace std;

  3. main() {
  4.   int T, A, B, prob = 1;
  5.   for (cin >> T; T--;) {
  6.     cin >> A >> B;
  7.     int p10 = 1, ret = 0;
  8.     while (p10 * 10 <= A) p10 *= 10;
  9.     for (int x = A; x <= B; x++) {
  10.       int y = x;
  11.       do {
  12.         if (y > x && y <= B) ret++;
  13.         y = y/10 + p10 * (y%10);
  14.       } while (y != x);
  15.     }
  16.     cout << "Case #" << prob++ << ": " << ret << endl;
  17.   }
  18. }


阅读(1042) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~