【noip2012 提高组 day1】

A.【NOIP2012 提高组 day1】Vigenère密码

思路:按照题目思路进行模拟

观察图后,可以发现规律

              m=c-(k-'a');

这时若m<'a' 则 m='z'-('a'-m-1);

然后将答案输出即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 string k;
 5 char m,c;
 6 int x=0,l;
 7 
 8 bool small(char s){
 9     if(s>='a'&&s<='z') return 1;
10     return 0;
11 }
12 
13 bool big(char s){
14     if(s>='A'&&s<='Z') return 1;
15     return 0;
16 }
17 
18 int main(){
19     cin>>k;
20     l=k.size();
21     getchar();
22     while(scanf("%c",&c)){
23         if(!small(c) && !big(c)) break;
24         if(small(k[x])) m=c-(k[x]-'a');
25         else if(big(k[x])) m=c-(k[x]-'A');
26         if(small(c) && m<'a') m='z'-('a'-m-1);
27         else if(big(c) && m<'A') m='Z'-('A'-m-1);
28         x++;
29         if(x>=l) x=0;
30         printf("%c",m);
31     }
32     return 0;
33 }

B. 【NOIP2012 提高组 day1】国王游戏

思路:这是一道贪心题

贪心策略是将a*b的小的放在前面。

证明可使用微扰法:

先假设p1在前p2在后

所以ans1=max( a0/b1,a0*a1/b2)

然后将p1p2互换

ans2=max(a0/b2,a0*a2/b1)

我们设k1=a0/b1,k2=a0*a1/b2,k3=a0/b2,k4=a0*a2/b1

显然有 k4>k1,k2>k3

若ans1<ans2 

则 k4>k2

即:a2/b1>a1/b2

a1*b1<a2*b2

也就是只要满足这个条件,就是最优情况

这道题需要用到高精度

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int now[20010],sum[20010],ans[20010],add[20010];
 4 struct Node {
 5     int a;
 6     int b;
 7     long long a_b;
 8 }node[1010];
 9 inline int read(){
10     int x=0,f=1;
11     char s=getchar();
12     while(!isdigit(s)){
13         f*=(s=='-')? -1:1;
14         s=getchar();
15     }
16     do x=x*10+(s^48),s=getchar();
17     while(isdigit(s));
18     return x*f;
19 }
20 void times(int x) {
21     memset(add,0,sizeof(add));
22     for(int i=1;i<=ans[0];i++) {
23         ans[i]=ans[i]*x;
24         add[i+1]+=ans[i]/10;
25         ans[i]%=10;
26     }
27     for(int i=1;i<=ans[0]+4;i++) {
28         ans[i]+=add[i];
29         if(ans[i]>=10) {
30             ans[i+1]+=ans[i]/10;
31             ans[i]%=10;
32         }
33         if(ans[i]!=0) {
34             ans[0]=max(ans[0],i);
35         } 
36     }
37     return ;
38 }
39 int divite(int x) {
40     memset(add,0,sizeof(add));
41     int q=0;
42     for(int i=ans[0];i>=1;i--) {
43         q*=10;
44         q+=ans[i];
45         add[i]=q/x;
46         if(add[0]==0 && add[i]!=0) {
47             add[0]=i;
48         }
49         q%=x; 
50     }
51     return 0;
52 }
53 bool compare() {
54     if(sum[0]==add[0]) {
55         for(int i=add[0];i>=1;i--) {
56             if(add[i]>sum[i]) return 1;
57             if(add[i]<sum[i]) return 0;
58         }
59     }
60     if(add[0]>sum[0]) return 1;
61     if(add[0]<sum[0]) return 0;
62 }
63 void zh () {
64     memset(sum,0,sizeof(sum));
65     for(int i=add[0];i>=0;i--) {
66         sum[i]=add[i];
67     }
68     return ;
69 }
70 bool cmp(Node a,Node b) {
71     return a.a_b<b.a_b;
72 }
73 int main() {
74     int n=read();
75     for(int i=0;i<=n;i++) {
76         node[i].a=read(),node[i].b=read();
77         node[i].a_b=node[i].a*node[i].b;
78     }
79     sort(node+1,node+n+1,cmp);
80     ans[0]=1,ans[1]=1;
81     for(int i=1;i<=n;i++) {
82         times(node[i-1].a);
83         divite(node[i].b);
84         if(compare()) {
85             zh();
86         }
87     }
88     for(int i=sum[0];i>=1;i--)
89         printf("%d",sum[i]);
90     return 0;
91 } 

C. 【NOIP2012 提高组 day1】开车旅行

设f[i][j]为在位置i走2^j轮的位置,一轮就是A走和B走一次,fa[i][j]就是A在位置i走2^j轮的距离,fb[i][j]类同。

 另外:从每个点到下一个用倍增来优化

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <set>
  6 
  7 using namespace std;
  8 
  9 const int maxn = 100005;
 10 int n, x0, m, k,x1, na[maxn], nb[maxn],ans;
 11 long long ansa = 1e5,ansb = 0ll,fa[maxn][20], fb[maxn][20], f[maxn][20];
 12 
 13 struct node
 14 {
 15     int id, high;
 16     bool operator < (const node & b) const {
 17         return high < b.high;
 18     }
 19 }c[maxn];
 20 
 21 struct node2
 22 {
 23     int id, gaoducha;
 24     bool operator < (const node2 & b) const {
 25         if (gaoducha != b.gaoducha)
 26             return gaoducha < b.gaoducha;
 27         else
 28             return c[id].high < c[b.id].high;
 29     }
 30 }temp[5];
 31 
 32 set <node> s;
 33 
 34 void init(int i)
 35 {
 36     set <node> ::iterator it = s.find(c[i]);
 37     int j = 0;
 38     if (it != s.begin())
 39     {
 40         --it;
 41         temp[++j] = (node2) { it->id, abs(it->high - c[i].high) };
 42         if (it != s.begin())
 43         {
 44             --it;
 45             temp[++j] = (node2) { it->id, abs(it->high - c[i].high) };
 46             ++it;
 47         }
 48         ++it;
 49     }
 50     if ((++it) != s.end())
 51     {
 52         temp[++j] = (node2) { it->id, abs(it->high - c[i].high) };
 53         if ((++it) != s.end())
 54             temp[++j] = (node2) { it->id, abs(it->high - c[i].high) };
 55     }
 56     sort(temp + 1, temp + j + 1);
 57     nb[i] = temp[1].id;
 58     if (j == 1)
 59         return;
 60     na[i] = temp[2].id;
 61     return;
 62 }
 63 
 64 void query(int st, int x, long long &ta, long long &tb)
 65 {
 66     for (int i = 19; i >= 0; i--)
 67         if (f[st][i] && fa[st][i] + fb[st][i] <= x)
 68         {
 69             ta += fa[st][i];
 70             tb += fb[st][i];
 71             x -= fa[st][i] + fb[st][i];
 72             st = f[st][i];
 73         }
 74     if (!na[st])
 75         return;
 76     int tempans = abs(c[na[st]].high - c[st].high);
 77     if (tempans <= x)
 78         ta += tempans;
 79 }
 80 
 81 int main()
 82 {
 83     scanf("%d", &n);
 84     for (int i = 1; i <= n; i++)
 85     {
 86         scanf("%d", &c[i].high);
 87         c[i].id = i;
 88     }
 89     for (int i = n; i;i--)
 90     {
 91         s.insert(c[i]);
 92         if (i != n)
 93             init(i);
 94     }
 95     for (int i = 1; i <= n; i++)
 96     {
 97         int p1 = na[i], p2 = nb[na[i]];
 98         fa[i][0] = p1 ? abs(c[p1].high - c[i].high) : 0;
 99         fb[i][0] = p2 ? abs(c[p2].high - c[p1].high) : 0;
100         f[i][0] = p2;
101     }
102     for (int j = 1; j < 20;j++) 
103         for (int i = 1; i <= n; i++)
104         {
105             f[i][j] = f[f[i][j - 1]][j - 1];
106             fa[i][j] = fa[i][j - 1] + fa[f[i][j - 1]][j - 1];
107             fb[i][j] = fb[i][j - 1] + fb[f[i][j - 1]][j - 1];
108         }
109     scanf("%d", &x0);
110     ans = 0;
111     for (int i = 1; i <= n; i++)
112     {
113         long long ta = 0ll, tb = 0ll;
114         query(i, x0, ta, tb);
115         if (tb && (!ans || ansa * tb > ansb * ta))
116         {
117             ansa = ta;
118             ansb = tb;
119             ans = i;
120         }
121     }
122     printf("%d
", ans);
123     scanf("%d", &m);
124     while (m--)
125     {
126         scanf("%d%d", &k, &x1);
127         long long ta = 0ll, tb = 0ll;
128         query(k, x1, ta, tb);
129         printf("%d %d
", ta, tb);
130     }
131     return 0;
132 }
原文地址:https://www.cnblogs.com/lirh04/p/12639074.html