算法学社
記錄難忘的征途
posts - 141,comments - 220,trackbacks - 0
吐槽:
   1. 模电铁定要挂了... Oh...No...
   2. 一次挂两题,错过了升黄的大好机会.
250pt:
    定义一个数S的序列{A} = F(S) = if(i == 0) Ai = S; else if(Ai-1 % 2 == 0) Ai = Ai-1 /2 ; else Ai = Ai-1 - 1;
    给三个长整型 K,A,B (小于1,000,000,000,000,000,000). 请问在区间[A,B]中的所有S对应的所有F(S)中K出现了几次.
算法分析:
    用二进制的角度去思考就很简单了... 额外要注意K=0和K=1的情况. 我就是考虑了K=0而没有考虑K=1而挂掉的..
 1 #include<iostream>
 2 using namespace std;
 3 long long chk(unsigned long long A, long long B, int v){
 4 //  cout<<(A>>v)<<" "<<(B>>v)<<endl;
 5   if((A>>v) == (B>>v)) {
 6     return B-A+1;
 7   }
 8 //  cout<<"chk: "<<(1LL<<v)<<endl;
 9   return 1LL<<v;
10 }
11 long long cal(long long A, long long B){
12   if(A > B) return 0;
13   if(A==0 || A==1) return B+1-A;
14   bool flag = A & 1;
15   int v = 0;
16   long long ans = 0;
17   long long At = A+1;
18   while(1){
19     if(!flag && At <= B) ans += chk(At,B,v);
20     if(A <= B) ans += chk(A,B,v) ; else break;
21   //  cout<<ans<<endl;
22     A <<=1; At<<=1; v++; 
23   }
24   cout<<"ans: "<<ans<<endl;
25   return ans;
26 }
27 class KleofasTail{
28   public : long long countGoodSequences(long long K, long long A, long long B){
29    // cout<<cal(K,B)<<" "<<cal(K,A-1)<<endl;
30     return cal(K,B) - cal(K,A-1);
31   }
32 };
33 
500pt:
    问满足大于A(A<1,000,000,000,000,000)的且digit1至少出现count1次,digit2至少出现count2次的最小的数是多少?
    (count1+count2<15,digit1,digit2<10)
算法分析:
    利用数位DP的思想,从右相左依次判断让前i位完全活动是否是可行方案,显然第一个可行方案就是答案,将“自由活动”的数位构造一下就可以了。我没有将digit1和digit2的大小排序,结果输出了次优解。
 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 typedef long long ll;
 5 int hash[11];
 6 bool fit(long long N, int a,int &c1, int b, int &c2){
 7     //cout<<N<<" ";
 8     while(N){
 9         ll x = N % 10;
10         if(x == a && c1) c1--;
11         if(x == b && c2) c2--;
12         N /= 10;
13     }
14     return  !c1 && !c2;
15 }
16 ll cal(int a,int c1,int b,int c2){
17     cout<<"cal: "<<a<<" "<<c1<<" "<<b<<" "<<c2<<endl;
18     int n = c1+c2; ll ans = 0;
19     for(int i=0; i < n; i++){
20         ans *= 10;
21         if(c1){
22             ans += a;
23             c1 --;
24         }
25         else {
26             ans += b;
27             c2 --;
28         }
29     }
30     return ans;
31 }
32 class FavouriteDigits{
33     public : long long findNext(long long N, int digit1, int count1, int digit2, int count2){
34         if(digit1 > digit2){ swap(digit1,digit2); swap(count1,count2); }
35         int cnt1 = count1, cnt2 = count2;
36         ll base[20];
37         base[0] = 1;
38         for(int i=1;i<20;i++) base[i] = base[i-1] * 10;
39         if(fit(N,digit1,cnt1,digit2,cnt2)) return N;
40         int flag = 0;
41         while(1){
42             ll D = N%10;
43             cnt1 = count1, cnt2 = count2;    
44             ll M = N+1;
45             fit(M,digit1,cnt1,digit2,cnt2);
46             if(flag >= cnt1+cnt2) return M*base[flag] + cal(digit1,cnt1,digit2,cnt2);
47             cnt1 = count1, cnt2 = count2;
48             if(D < digit1){    
49                 M = N/10*10 + digit1;
50                 fit(M,digit1,cnt1,digit2,cnt2);
51                 if(flag >= cnt1+cnt2) return M*base[flag] + cal(digit1,cnt1,digit2,cnt2);
52             }
53             cnt1 = count1, cnt2 = count2;
54             if(D < digit2){
55                 M = N/10*10 + digit2;
56                 fit(M,digit1,cnt1,digit2,cnt2);
57                 if(flag >= cnt1+cnt2) return M*base[flag] + cal(digit1,cnt1,digit2,cnt2);
58             }
59             N/=10; flag ++;
60         }
61     }
62 };
posted on 2012-06-17 09:46 西月弦 阅读(406) 评论(0)  编辑 收藏 引用 所属分类: 比赛感言

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理