Gym - 101411H Hotel in Ves Lagos 数位DP 2009-2010 ACM-ICPC, NEERC, Western Subregional Contest
2017-07-19 19:37
661 查看
http://codeforces.com/gym/101411/attachments
Problem H. Hotel in Ves Lagos
Input le: hotel.in
Output le: hotel.out
Time limit: 1 second
Memory limit: 256 megabytes
A new hotel is being built in the city of Ves Lagos. The hotel will have an in finite number of rooms(it is out of fashion to build hotels with fi nite numbers of rooms). The new hotel also tries to cater for superstitious guests.
The most common superstition in Ves Lagos is that the number 13 brings bad luck. Accordingly, only numbers whose decimal forms do not contain the substring \13" will be used to label the rooms in the new hotel. For example, the
hotel will have rooms numbered 1, 3, 14, 31, 123, but will not have the rooms 13, 132, 913, 1308, 1313.
Let's consider the list of all room numbers, ordered increasingly. Find the N-th number in this list(members of the list are indexed from 1).
Input
The input contains several test cases.
The 1st line contains T (1 ≤ T ≤ 100), the number of test cases. Each of the following T lines describes one test case and contains the integer N(1 ≤ N ≤ 1018).
Output
The output le should contain exactly T lines, with the i-th line containing exactly one integer, the answer for the i-th test case from the input.
Example
hotel.in
3
20
150
1
hotel.out
20
162
1
找到第i个数字中不含有13的数。
与一般的数位DP不同,这题要求找到满足条件的第i个数。
我们只需要二分这个数,求出小于等于这个数的满足条件的数的数量,看何时满足条件。
有个细节需要注意,二分后的数不一定是正确答案。要使solve(k)为题目所给数n,而solve(k-1)为n-1.因为当二分所得的数含有13时,solve该数的值与它之前第一个符合条件的值相等。
这就需要玄学调整答案了。。。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <bitset>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
int num[20];
ll dp[20][2];
ll dfs(int len,bool pre,bool HaveLimit) {
if (len==0) return 1;
if (dp[len][pre]!=-1&&!HaveLimit)
return dp[len][pre];
int l=HaveLimit?num[len]:9;
ll ans=0;
for (int i=0;i<=l;i++) {
if (i==3&&pre) continue;
ans+=dfs(len-1,i==1,HaveLimit&&i==num[len]);
}
if (!HaveLimit) dp[len][pre]=ans;
return ans;
}
ll solve(ll n) {
ll k=n;
int i=0;
while (k) {
num[++i]=k%10;
k/=10;
}
ll ans=dfs(i,0,1);
return ans-1;
}
int main() {
// freopen("hotel.in","r",stdin);
// freopen("hotel.out","w",stdout);
int cas;
scanf("%d",&cas);
memset(dp,-1,sizeof(dp));
while (cas--) {
ll n,i,l,r,mid;
scanf("%lld",&n);
l=1;r=15e17;
while (l<=r) {
mid=(l+r)/2;
ll f=solve(mid);
// cout << mid << ' ' << f << endl;
if (f>=n) r=mid-1; else
if (f<n) l=mid+1;
}
while (solve(mid-1)>=n) mid--;
while (solve(mid)<n) mid++;
printf("%lld\n",mid);
}
return 0;
}
Problem H. Hotel in Ves Lagos
Input le: hotel.in
Output le: hotel.out
Time limit: 1 second
Memory limit: 256 megabytes
A new hotel is being built in the city of Ves Lagos. The hotel will have an in finite number of rooms(it is out of fashion to build hotels with fi nite numbers of rooms). The new hotel also tries to cater for superstitious guests.
The most common superstition in Ves Lagos is that the number 13 brings bad luck. Accordingly, only numbers whose decimal forms do not contain the substring \13" will be used to label the rooms in the new hotel. For example, the
hotel will have rooms numbered 1, 3, 14, 31, 123, but will not have the rooms 13, 132, 913, 1308, 1313.
Let's consider the list of all room numbers, ordered increasingly. Find the N-th number in this list(members of the list are indexed from 1).
Input
The input contains several test cases.
The 1st line contains T (1 ≤ T ≤ 100), the number of test cases. Each of the following T lines describes one test case and contains the integer N(1 ≤ N ≤ 1018).
Output
The output le should contain exactly T lines, with the i-th line containing exactly one integer, the answer for the i-th test case from the input.
Example
hotel.in
3
20
150
1
hotel.out
20
162
1
找到第i个数字中不含有13的数。
与一般的数位DP不同,这题要求找到满足条件的第i个数。
我们只需要二分这个数,求出小于等于这个数的满足条件的数的数量,看何时满足条件。
有个细节需要注意,二分后的数不一定是正确答案。要使solve(k)为题目所给数n,而solve(k-1)为n-1.因为当二分所得的数含有13时,solve该数的值与它之前第一个符合条件的值相等。
这就需要玄学调整答案了。。。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <bitset>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
int num[20];
ll dp[20][2];
ll dfs(int len,bool pre,bool HaveLimit) {
if (len==0) return 1;
if (dp[len][pre]!=-1&&!HaveLimit)
return dp[len][pre];
int l=HaveLimit?num[len]:9;
ll ans=0;
for (int i=0;i<=l;i++) {
if (i==3&&pre) continue;
ans+=dfs(len-1,i==1,HaveLimit&&i==num[len]);
}
if (!HaveLimit) dp[len][pre]=ans;
return ans;
}
ll solve(ll n) {
ll k=n;
int i=0;
while (k) {
num[++i]=k%10;
k/=10;
}
ll ans=dfs(i,0,1);
return ans-1;
}
int main() {
// freopen("hotel.in","r",stdin);
// freopen("hotel.out","w",stdout);
int cas;
scanf("%d",&cas);
memset(dp,-1,sizeof(dp));
while (cas--) {
ll n,i,l,r,mid;
scanf("%lld",&n);
l=1;r=15e17;
while (l<=r) {
mid=(l+r)/2;
ll f=solve(mid);
// cout << mid << ' ' << f << endl;
if (f>=n) r=mid-1; else
if (f<n) l=mid+1;
}
while (solve(mid-1)>=n) mid--;
while (solve(mid)<n) mid++;
printf("%lld\n",mid);
}
return 0;
}
相关文章推荐
- 2009-2010 ACM-ICPC, NEERC, Western Subregional Contest
- 2009-2010 ACM-ICPC, NEERC, Southern Subregional Contest B kakuro
- [Gym]2008-2009 ACM-ICPC, NEERC, Moscow Subregional Contest
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem D. Distance 迪杰斯特拉
- Gym - 100792A Anagrams (2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest)
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem F. Finance 模拟题
- 2010-2011 ACM-ICPC, NEERC, Southern Subregional Contest【solved :8 / 12 】
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem H. Hometask 水题
- 2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest H题: Hashing [基础DP]
- 2013-2014 ACM-ICPC, NEERC, Southern Subregional Contest Problem H. Password Service dp
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem I. Interest Targeting 模拟题
- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest - J. Bottles(DP)
- 2008-2009 ACM-ICPC, NEERC, Southern Subregional Contest
- C. Explode 'Em All 搜索 2010-2011 ACM-ICPC, NEERC, Southern Subregional Contest
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem J. Joke 水题
- Codeforces 730 J. Bottles DP 0-1背包- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem K. KMC Attacks 交互题 暴力
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem A. Alien Visit 计算几何
- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest J dp
- 2010-2011 ACM-ICPC, NEERC, Southern Subregional Contest Fire in the Country(博弈论+搜索)