NEERC 2010, Eastern subregional contest

 

只能把补了的题目放这儿了,先留个坑,怕忘记。

Problem G URAL 1806 Mobile Telegraphs

题意是:给定n个电话号码,每个号码是一个长度为10的仅含'0'~'9'的字符串,每两个电话号码a,b之间能通信,需要满足一下条件之一:

1.b能通过改变a中某一个数字的值获得;

2.b能通过交换a中两个数字获得。

n个电话号码不相同,且相互通信的费用由之间的最长公共前缀长度决定。

分析:

对于一个电话号码逐位判断改变某一位的值得到哪些号码,或者交换某两个数字的得到哪些号码,由此判断该号码能与哪些号码通信,通信费用也可以很快求出。

然后就是dijkstra 或者spfa了。注意map存储LL判断的时候,前导0 可能会被忽略。

另外在spfa或dij里面进行边的转移,而不事先把边求出来可以加速过程。

  1 #include <bits/stdc++.h>
  2 #define  esp 1e-6
  3 #define  inf 0x3f3f3f3f
  4 #define  pi acos(-1.0)
  5 #define  pb push_back
  6 #define  lson l, m, rt<<1
  7 #define  rson m+1, r, rt<<1|1
  8 #define  lowbit(x) (x&(-x))
  9 #define  mp(a, b) make_pair((a), (b))
 10 #define  bit(k) (1<<(k))
 11 #define  iin  freopen("pow.in", "r", stdin);
 12 #define  oout freopen("pow.out", "w", stdout);
 13 #define  in  freopen("solve_in.txt", "r", stdin);
 14 #define  out freopen("solve_out.txt", "w", stdout);
 15 #define  bug puts("********))))))");
 16 #define  Inout iin oout
 17 #define  inout in out
 18 
 19 #define  SET(a, v) memset(a, (v), sizeof(a))
 20 #define  SORT(a)   sort((a).begin(), (a).end())
 21 #define  REV(a)    reverse((a).begin(), (a).end())
 22 #define  READ(a, n) {REP(i, n) cin>>(a)[i];}
 23 #define  REP(i, n) for(int i = 0; i < (n); i++)
 24 #define  VREP(i, n, base) for(int i = (n); i >= (base); i--)
 25 #define  Rep(i, base, n) for(int i = (base); i < (n); i++)
 26 #define  REPS(s, i) for(int i = 0; (s)[i]; i++)
 27 #define  pf(x) ((x)*(x))
 28 #define  mod(n) ((n))
 29 #define  Log(a, b) (log((double)b)/log((double)a))
 30 #define Srand() srand((int)time(0))
 31 #define random(number) (rand()%number)
 32 #define random_range(a, b) (int)(((double)rand()/RAND_MAX)*(b-a) + a)
 33 
 34 using namespace std;
 35 typedef long long  LL;
 36 typedef unsigned long long ULL;
 37 typedef vector<unsigned short> VI;
 38 typedef pair<unsigned short,unsigned short> PII;
 39 typedef vector<PII> VII;
 40 typedef vector<PII, int> VIII;
 41 typedef VI:: iterator IT;
 42 typedef map<string, int> Mps;
 43 typedef map<LL, int> Mpi;
 44 typedef map<int, PII> Mpii;
 45 typedef map<PII, int> Mpiii;
 46 Mpi mps;
 47 const int maxn = 20;
 48 const int maxm = 50000 + 100;
 49 
 50 unsigned short co[maxn];
 51 unsigned short pa[maxm];
 52 LL a[12];
 53 
 54 LL s[maxm];
 55 int n;
 56 int d[maxm];
 57 bool inq[maxm];
 58 
 59 VII g[maxm];
 60 struct HeapNode
 61 {
 62     int d;
 63     unsigned short u;
 64     HeapNode() {}
 65     HeapNode(int d, unsigned short u):d(d), u(u) {}
 66     bool operator < (const HeapNode &rhs)const
 67     {
 68         return d > rhs.d;
 69     }
 70 };
 71 unsigned short cmp1(LL x, LL y)
 72 {
 73     char ss[2][12];
 74     sprintf(ss[0], "%010I64d", x);
 75     sprintf(ss[1] ,"%010I64d", y);
 76     int i = 0;
 77     for(i = 0; i <= 9; i++)
 78     {
 79         if(ss[0][i] != ss[1][i])
 80             break;
 81     }
 82     return co[i];
 83 }
 84 void bfs(int src)
 85 {
 86     priority_queue<HeapNode> q;
 87     q.push(HeapNode(0, src));
 88     d[src] = 0;
 89     inq[src] = false;
 90     while(!q.empty())
 91     {
 92         HeapNode u = q.top();
 93         int x = u.u;
 94         int dd = u.d;
 95         q.pop();
 96         if(inq[x])
 97             continue;
 98         inq[x] = true;
 99         char ss[12];
100         sprintf(ss+1, "%010I64d", s[x]);
101         Rep(j, 1, 11)
102         {
103             int c = ss[11-j]-'0';
104             REP(k, 10)
105             {
106                 if(k == c)
107                     continue;
108                 LL tmp = s[x] + (k-c)*a[j-1];
109                 if(mps.count(tmp))
110                 {
111                     int y = mps[tmp];
112                     int l = cmp1(s[x], s[y]);
113                     if(d[y] > dd + l)
114                     {
115                         pa[y] = x;
116                         d[y] = dd + l;
117                         q.push(HeapNode(d[y], y));
118                     }
119                 }
120             }
121         }
122         Rep(j, 1, 11) for(int k = j+1; k <= 10; k++)
123         {
124             int c1 = ss[11-j]-'0';
125             int c2 = ss[11-k]-'0';
126             if(c1 == c2)
127                 continue;
128             LL tmp = s[x] + (c2-c1)*a[j-1] + (c1-c2)*a[k-1];
129             if(mps.count(tmp))
130             {
131                 int y = mps[tmp];
132                 int l = cmp1(s[x], s[y]);
133                 if(d[y] >dd + l)
134                 {
135                     pa[y] = x;
136                     d[y] = dd + l;
137                     q.push(HeapNode(d[y], y));
138                 }
139             }
140         }
141     }
142 }
143 VI ans;
144 
145 void print(int s)
146 {
147     ans.pb(s);
148     while(1)
149     {
150         s = pa[s];
151         ans.pb(s);
152         if(s == 1)
153             break;
154     }
155     printf("%d\n", ans.size());
156     VREP(i, ans.size()-1, 0)
157     {
158         printf("%hu%c", ans[i], i == 0 ? '\n' : ' ');
159     }
160 }
161 int main()
162 {
163 
164     a[0] = 1;
165     Rep(i, 1, 11)
166     a[i] = a[i-1]*10;
167     scanf("%d", &n);
168     REP(i, 10)
169     scanf("%hu", co+i);
170     Rep(i, 1, n+1)
171     {
172         scanf("%I64d", s+i);
173         mps[s[i]] = i;
174         d[i] = inf;
175         inq[i] = false;
176     }
177 
178     bfs(1);
179     if(d[n] >= inf)
180         puts("-1");
181     else
182     {
183         printf("%d\n", d[n]);
184         print(n);
185     }
186     return 0;
187 }
View Code

Problem D URAL 1803 The Czechs' Rifles

题意:实际上就是要你求出前n个斐波那契数的k进制表示下,各个位数之和,然后再排序输出。

分析首先可以证明的是,fn <= 2*fn-1,所以fn <= 2^n,所以可以这样求每个斐波那契数的k进制表示下各数位之和,将其表示成cnt进制的数,cnt为不超过n的k的最大次幂,

然后预处理出来小于cnt的各个数的k进制下数位之和。接下来就是通过前两项酸算出当前的斐波那契数,然后并将其k进制下各位加起来。这个过程其实就是模拟的一个大数加法的过程。

 

 1 #include <bits/stdc++.h>
 2 #define  in  freopen("solve_in.txt", "r", stdin);
 3 using namespace std;
 4 const int maxn = 50000 + 100;
 5 struct Node
 6 {
 7     int id, su;
 8     bool operator < (const Node &rhs)const
 9     {
10         if(su == rhs.su)
11             return id < rhs.id;
12         return su < rhs.su;
13     }
14 } ans[maxn];
15 int sum[maxn];
16 int dp[2][maxn];
17 
18 int n, k;
19 int main()
20 {
21     
22     scanf("%d%d", &k, &n);
23     int cnt = 1;
24     while(cnt * k < maxn)
25         cnt *= k;
26     for(int i = 0; i < maxn; i++)
27     {
28         int tmp = i;
29         while(tmp)
30         {
31             sum[i] += tmp%k;
32             tmp /= k;
33         }
34     }
35     dp[0][0] = dp[1][0] = 1;
36     ans[1].id = 1, ans[2].id  = 2;
37     ans[1].su = ans[2].su = 1;
38     int st = 1;
39     for(int i = 3; i <= n; i++)
40     {
41         int delta = 0;
42         int now = i&1;
43         int pre = now^1;
44         ans[i].id = i;
45         for(int k = 0; k < st; k++)
46         {
47             dp[now][k] += dp[pre][k] + delta;
48             if(dp[now][k] >= cnt)
49             {
50                 delta = dp[now][k]/cnt;
51                 dp[now][k] %= cnt;
52             }
53             else delta = 0;
54             ans[i].su += sum[dp[now][k]];
55         }
56         if(delta)
57             dp[now][st++] = delta;
58         ans[i].su += sum[delta];
59     }
60     std::sort(ans+1, ans+1+n);
61     for(int i = 1; i <= n; i++)
62         printf("%d%c", ans[i].id, i == n ? '\n' : ' ');
63     return 0;
64 }
View Code

posted on 2014-08-10 12:09  rootial  阅读(283)  评论(0编辑  收藏  举报

导航