TopCoder SRM 403 DIV 2
Problem | Check | Points |
250 | ○ | 239.31 |
500 | × | - |
1000 | - | - |
最近練習で500を落とすなあ。無理やりやろうとしてわけがわからなくなるパターンが多いので、まずは1000までとかよくばらずに500を確実にできるように。
今日の練習会のMVPは@Matsu4512。全部通しやがった・・・
Problem 250 TheLargestLuckyNumber
John thinks 4 and 7 are lucky digits, and all other digits are not lucky. A lucky number is a number that contains only lucky digits in decimal notation.
You are given an int n. Return the largest lucky number that is less than or equal to n.
deque<int> integerDigits(int x){ deque<int> arr; while(x!=0){ arr.push_front(x%10); x/=10; } return arr; } class TheLargestLuckyNumber { public: int find(int n) { deque<int> a; bool b; for(int i=n ; i>=4 ; i--){ a = integerDigits(i); b = true; for(int j=0 ; j<a.size() ; j++){ if(a[j]!=4 && a[j]!=7){ b = false; break; } } if(b) return i; } return 4; } };
Problem 500 TheLuckyNumbers
John thinks 4 and 7 are lucky digits, and all other digits are not lucky. A lucky number is a number that contains only lucky digits in decimal notation.
You are given ints a and b. Return the number of lucky numbers between a and b, inclusive.
実装が糞になってしまった。countLuckyがあればfindMinLuckyとfindMaxLuckyなんていらないと気づいたのがついさっき。直す気力がありません
int findMinLucky(int a, int b){ if(a>777777777) return -1; if(77777777<a && a<444444444 && 444444444<b) return 444444444; int k; bool f; for(int i=a ; i<=b ; i++){ k = i; f = true; while(k!=0){ if(k%10!=4 && k%10!=7){ f = false; break; } k /= 10; } if(f) return i; } return -1; } int findMaxLucky(int a){ if(a>777777777) return 777777777; if(a>77777777 && a<444444444) return 77777777; int k; bool b; for(int i=a ; i>=4 ; i--){ k = i; b = true; while(k!=0){ if(k%10!=4 && k%10!=7){ b = false; break; } k /= 10; } if(b) return i; } return -1; } deque<int> integerDigits(int x){ deque<int> arr; while(x!=0){ arr.push_front(x%10); x/=10; } return arr; } int countLucky(deque<int> d1, deque<int> d2){ int cnt = 1; while(d1!=d2){ cnt++; bool f = true; for(int i=d1.size()-1 ; i>=0 ; i--){ if(d1[i]==4){ d1[i]=7; f = false; break; } else d1[i] = 4; } if(f) d1.push_front(4); } return cnt; } class TheLuckyNumbers { public: int count(int a, int b) { int kmin = findMinLucky(a,b); int kmax = findMaxLucky(b); cout << kmin << " " <<kmax << endl; if(kmin==-1) return 0; deque<int> d1 = integerDigits(kmin); deque<int> d2 = integerDigits(kmax); return countLucky(d1,d2); } };
Problem 1000
John thinks 4 and 7 are lucky digits, and all other digits are not lucky. A lucky number is a number that contains only lucky digits in decimal notation.
Some numbers can be represented as a sum of only lucky numbers. Given an int n, return a int whose elements sum to exactly n. Each element of the int must be a lucky number. If there are multiple solutions, only consider those that contain the minimum possible number of elements, and return the one among those that comes earliest lexicographically. A int a1 comes before a int a2 lexicographically if a1 contains a smaller number at the first position where they differ. If n cannot be represented as a sum of lucky numbers, return an empty int[] instead.
500の実装が腐っていたので1000までひきずるはめに。DP部分は@Matsu4512の作品、勉強になります。
vector<int> v; int findMinLucky(int a, int b){ int k; bool f; for(int i=a ; i<=b ; i++){ k = i; f = true; while(k!=0){ if(k%10!=4 && k%10!=7){ f = false; break; } k /= 10; } if(f) return i; } return -1; } int findMaxLucky(int a){ int k; bool b; for(int i=a ; i>=4 ; i--){ k = i; b = true; while(k!=0){ if(k%10!=4 && k%10!=7){ b = false; break; } k /= 10; } if(b) return i; } return -1; } deque<int> integerDigits(int x){ deque<int> arr; while(x!=0){ arr.push_front(x%10); x/=10; } return arr; } int fromDigits(deque<int> arr){ int x=0; while(!arr.empty()){ x *= 10; x += arr[0]; arr.pop_front(); } return x; } void calcLucky(deque<int> d1, deque<int> d2){ while(d1!=d2){ v.push_back(fromDigits(d1)); bool f = true; for(int i=d1.size()-1 ; i>=0 ; i--){ if(d1[i]==4){ d1[i]=7; f = false; break; } else d1[i] = 4; } if(f) d1.push_front(4); } v.push_back(fromDigits(d1)); return; } int sumdeq(deque<int> a){ int sum=0; for(int i=0 ; i<a.size() ; i++){ sum += a[i]; } return sum; } int nn; int dp[1000001]; vector<int> nums[1000001]; void dpcalc(){ dp[0] = 0; dp[1] = dp[2] = dp[3] = 1000000; int mina, a; vector<int> min_vec; for(int i=4; i<=nn ; i++){ mina = 1000000; min_vec.clear(); for(int j=0 ; j<v.size() ; j++){ if(i-v[j]<0) break; if(mina > dp[i-v[j]]){ a = v[j]; mina = dp[i-a]; min_vec = nums[i-a]; } } dp[i] = mina+1; if(mina != 1000000) min_vec.push_back(a); nums[i] = min_vec; } } class TheSumOfLuckyNumbers { public: vector <int> sum(int n) { v.clear(); nn = n; int kmin = 4; int kmax = findMaxLucky(n); if(kmax==-1) return vector<int>(); deque<int> d1 = integerDigits(kmin); deque<int> d2 = integerDigits(kmax); calcLucky(d1,d2); dpcalc(); if(nums[n].size()>0) sort(nums[n].begin(), nums[n].end()); return nums[n]; } };