2016百度之星 初赛2A ABEF

只做了1001 1002 1005 1006。剩下2题可能以后补?

http://acm.hdu.edu.cn/search.php?field=problem&key=2016%22%B0%D9%B6%C8%D6%AE%D0%C7%22+-+%B3%F5%C8%FC%A3%A8Astar+Round2A%A3%A9&source=1&searchmode=source

Solved Pro.ID Title Author Source (AC/Submit)Ratio
You has solved this problem :-) 5690 All X   2016"百度之星" - 初赛(Astar Round2A) (438/912)48.03%
You has solved this problem :-) 5691 Sitting in Line   2016"百度之星" - 初赛(Astar Round2A) (255/566)45.05%
  5692 Snacks   2016"百度之星" - 初赛(Astar Round2A) (148/689)21.48%
  5693 D Game   2016"百度之星" - 初赛(Astar Round2A) (70/212)33.02%
You has solved this problem :-) 5694 BD String   2016"百度之星" - 初赛(Astar Round2A) (214/477)44.86%
You has solved this problem :-) 5695 Gym Class   2016"百度之星" - 初赛(Astar Round2A) (266/668)39.82%

题面看不清楚的可以去下面这个比赛网址看,但是交题要去上面这些交。

http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=701

都是题面很明显的中文题,我就不写题意了。

1001 All X

题解:

2种解法:1.矩阵快速幂 2.找循环节。我用的是找循环节。

1.快速幂解法:乘十加一这个操作可以转化为乘上一个2*2的矩阵的操作,用快速幂把一大堆矩阵算完,就无敌了。

2.找循环节,观察MOD数不到1W,所以算着算着肯定会出现重复的数,然后就会循环,我们可以跳过若干循环,直接算最后不到1W步的地方。

设y,循环使y=(y*10+1)%MOD,将每个y记录,a[y] = step。a数组初始化-1,当发现a[y]不为-1时,就循环了。

注意有地方要用long long。

代码:

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 
14 #define MZ(array) memset(array, 0, sizeof(array))
15 #define MF1(array) memset(array, -1, sizeof(array))
16 #define MINF(array) memset(array, 0x3f, sizeof(array))
17 #define REP(i,n) for(i=0;i<(n);i++)
18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
19 #define ROF(i,x,y) for(i=(x);i>=(y);i--)
20 #define RD(x) scanf("%d",&x)
21 #define RD2(x,y) scanf("%d%d",&x,&y)
22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
23 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
24 #define WN(x) printf("%d\n",x);
25 #define RE  freopen("D.in","r",stdin)
26 #define WE  freopen("huzhi.txt","w",stdout)
27 #define MP make_pair
28 #define PB push_back
29 #define PF push_front
30 #define PPF pop_front
31 #define PPB pop_back
32 #define lowbit(x) ((x)&(-x))
33 template<class T>inline void OA(const T &a,const int &st,const int &ed) {
34     if(ed>=st)cout<<a[st];
35     int i;
36     FOR(i,st+1,ed)cout<<' '<<a[i];
37     puts("");
38 }
39 typedef long long LL;
40 typedef unsigned long long ULL;
41 const double PI=acos(-1.0);
42 const double EPS=1e-10;
43 inline int sgn(double &x) {
44     if(fabs(x) < EPS)return 0;
45     if(x < 0)return -1;
46     else return 1;
47 }
48 
49 const int MAXN=111111;
50 const int MAXM=33;
51 
52 LL x,k,c;
53 LL m;
54 
55 LL h[11111];
56 
57 bool farm() {
58     LL y = 0;
59     LL l = 0;
60     MF1(h);
61     h[0] = 0;
62     while(l<m) {
63         y = y*10+x;
64         y %= k;
65         l++;
66         if(h[y]!=-1) {
67             break;
68         }
69         h[y] = l;
70     }
71     if(l<m) {
72         LL st = h[y];
73         LL ed = l;
74         LL step = ed - st;
75         LL jump = (m-l)/step;
76         l += jump*step;
77         while(l<m) {
78             y = y*10+x;
79             y %= k;
80             l++;
81         }
82     }
83 
84     return y==c;
85 }
86 
87 int main() {
88     int i;
89     int T,t=1;
90     RD(T);
91     while(T--) {
92         cin>>x>>m>>k>>c;
93         printf("Case #%d:\n",t++);
94         if(farm())puts("Yes");
95         else puts("No");
96     }
97     return 0;
98 }
View Code

 

1002 Sitting in Line

题解:

状压动规。

注意只有16个数,用了哪些数的状态可以用16位二进制表示。然后想局部最优性,我们可以先算前x个位置放各种数的情况,再推到x+1位置,所需要的信息是第x个是哪个数。

可以设定状态dp[x][y],x为那个16位二进制,y为已放好的数中最右边那个是什么。

就一顿状态转移。如果已经有数占据一个位置了,就只转移到以这个数结尾的状态。

(可恶,这题我比赛时没想出来,动规苦手)

代码:

  1 #pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 
 14 #define MZ(array) memset(array, 0, sizeof(array))
 15 #define MF1(array) memset(array, -1, sizeof(array))
 16 #define MINF(array) memset(array, 0x3f, sizeof(array))
 17 #define REP(i,n) for(i=0;i<(n);i++)
 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 19 #define ROF(i,x,y) for(i=(x);i>=(y);i--)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
 24 #define WN(x) printf("%d\n",x);
 25 #define RE  freopen("D.in","r",stdin)
 26 #define WE  freopen("huzhi.txt","w",stdout)
 27 #define MP make_pair
 28 #define PB push_back
 29 #define PF push_front
 30 #define PPF pop_front
 31 #define PPB pop_back
 32 #define lowbit(x) ((x)&(-x))
 33 template<class T>inline void OA(const T &a,const int &st,const int &ed) {
 34     if(ed>=st)cout<<a[st];
 35     int i;
 36     FOR(i,st+1,ed)cout<<' '<<a[i];
 37     puts("");
 38 }
 39 typedef long long LL;
 40 typedef unsigned long long ULL;
 41 const double PI=acos(-1.0);
 42 const double EPS=1e-10;
 43 inline int sgn(double &x) {
 44     if(fabs(x) < EPS)return 0;
 45     if(x < 0)return -1;
 46     else return 1;
 47 }
 48 
 49 const int INF = 0x3f3f3f3f;
 50 const int MAXN=111111;
 51 const int MAXM=16;
 52 const int MM = 1111111;
 53 
 54 int n;
 55 int a[MAXM],p[MAXM];
 56 
 57 int b[1<<MAXM][MAXM];
 58 int c[MAXM];
 59 
 60 int q[2][MM];
 61 int w[2][MM];
 62 int qn[2];
 63 inline int farm() {
 64     int i,j,k,y;
 65     int now=0;
 66     int maxx = 1<<n;
 67     REP(i,maxx)REP(j,n)b[i][j]=-1;
 68     MF1(c);
 69     REP(i,n) {
 70         if(p[i]!=-1)c[p[i]]=i;
 71     }
 72     ///DP INIT
 73     int st,ed;
 74     if(c[0]==-1) {
 75         st=0;
 76         ed=n-1;
 77     } else st=ed=c[0];
 78 
 79     FOR(i,st,ed) {
 80         y = 1<<i;
 81         b[y][i] = 0;
 82         q[now][qn[now]] = y;
 83         w[now][qn[now]] = i;
 84         qn[now]++;
 85     }
 86     now^=1;
 87     int ans=0x80000001;
 88     ///DP zhuan yi
 89     FOR(i,1,n-1) {
 90         int &nn = qn[now];
 91         int &pn = qn[now^1];
 92         int st,ed;
 93         if(c[i]!=-1) {
 94             st=ed=c[i];
 95         } else {
 96             st=0;
 97             ed=n-1;
 98         }
 99         nn=0;
100         FOR(j,st,ed) {
101             y = 1<<j;
102             REP(k,pn) {
103                 int &qq =q[now^1][k];
104                 int &ww = w[now^1][k];
105                 if((qq & y)!=0)continue;
106 //                printf("%d, %d:%d, %d:%d\n",i,j,a[j], k,ww);
107                 int z = qq | y;
108                 int newY = b[qq][ww] + a[ww] * a[j];
109                 if(b[z][j]==-1 || newY > b[z][j]) {
110                     b[z][j]=newY;
111 //                    printf("%d,%d,%d\n",z,j,newY);
112                     if(i==n-1) ans = max(ans, newY);
113                     q[now][nn] = z;
114                     w[now][nn] = j;
115                     nn++;
116                 }
117             }
118         }
119         now^=1;
120     }
121     return ans;
122 }
123 
124 int main() {
125     int i,x,y;
126     int L,R;
127     int T,t=1;
128     RD(T);
129     while(T--) {
130         RD(n);
131         REP(i,n)RD2(a[i],p[i]);
132         printf("Case #%d:\n",t++);
133         printf("%d\n",farm());
134     }
135     return 0;
136 }
View Code

 

1005 BD String

题解:

疯狂递归。

观察题目,可以发现这个第i个字符串的前半部分其实就是第i-1个字符串。它搞第2^1000个字符串,简直吓人,其实我们只用前面一小部分就行了。

用gank(L,R)递归求区间[L,R]的B数。

观察发现,那个中间的B总是在2的某次方上,我们要以这些B作为分界线。现在先称这些B为“中B”。

要求区间[L,R],我们找R左边的最右边的一个中B,这个中B,很关键。可以用log2得到。

如果L大于这个中B,我们可以根据规则递归,把区间以中B为轴,镜像到中B的左边。

如果区间包括中B,记得返回值要加1。

如果L小于这个中B,则[中B +1,R]这个区间根据上面的说法,是要镜像到左边的,这样就会和[L, 中B-1]重合,最后发现重合的这一段就抵消掉了(因为镜像到左边是要求D的数量,也就是总数减去B数,减去哦),所以我们只用算不重合的。

这样这个区间就会以log的速度减小,一下就算完了。

(比赛时没做出,没能认真下来思考题,被2^1000吓到了)

代码:

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 
14 #define MZ(array) memset(array, 0, sizeof(array))
15 #define MF1(array) memset(array, -1, sizeof(array))
16 #define MINF(array) memset(array, 0x3f, sizeof(array))
17 #define REP(i,n) for(i=0;i<(n);i++)
18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
19 #define ROF(i,x,y) for(i=(x);i>=(y);i--)
20 #define RD(x) scanf("%d",&x)
21 #define RD2(x,y) scanf("%d%d",&x,&y)
22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
23 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
24 #define WN(x) printf("%d\n",x);
25 #define RE  freopen("D.in","r",stdin)
26 #define WE  freopen("huzhi.txt","w",stdout)
27 #define MP make_pair
28 #define PB push_back
29 #define PF push_front
30 #define PPF pop_front
31 #define PPB pop_back
32 #define lowbit(x) ((x)&(-x))
33 template<class T>inline void OA(const T &a,const int &st,const int &ed) {
34     if(ed>=st)cout<<a[st];
35     int i;
36     FOR(i,st+1,ed)cout<<' '<<a[i];
37     puts("");
38 }
39 typedef long long LL;
40 typedef unsigned long long ULL;
41 const double PI=acos(-1.0);
42 const double EPS=1e-10;
43 inline int sgn(double &x) {
44     if(fabs(x) < EPS)return 0;
45     if(x < 0)return -1;
46     else return 1;
47 }
48 
49 const int MAXN=111111;
50 const int MAXM=33;
51 
52 int a[1];
53 
54 inline LL farm(const LL &l, const LL &r) {
55     if(l>r)return 0;
56     double lgr = log(r)/log(2);
57     int ilgr = floor(lgr );
58     LL edge = (1LL<<ilgr);
59 //    printf("[%I64d,%I64d],%I64d\n",l,r,edge);
60     if(l>edge){
61         return (r-l+1) - farm(edge - (r-edge),edge - (l-edge));
62     }else if(l<edge && r>edge){
63         LL re = 1;
64         if(r-edge > edge-l){
65             ///re += farm(l,edge-1) + (edge-l+1-1) - farm(l,edge-1);
66             re += edge-l;
67             re += farm(edge+(edge-l)+1, r);
68         }else{
69             ///re += (r-edge+1-1) - farm(edge - (r-edge) , edge - 1) + farm(...);
70             re += r-edge;
71             re += farm(l, edge - (r-edge) - 1);
72         }
73         return re;
74     }else if(l==edge){
75         if(r==edge) return 1;
76         else return (r-edge) - farm(edge - (r-edge),edge - 1) + 1;
77     }else if(r==edge){
78         return farm(l,r-1) + 1;
79     }else{
80         for(int i=0;true;i--)
81             a[i]++;
82     }
83 }
84 
85 int main() {
86     LL L,R;
87     int T;
88     RD(T);
89     while(T--) {
90         scanf("%I64d%I64d",&L,&R);
91         printf("%I64d\n",farm(L,R));
92     }
93     return 0;
94 }
View Code

 

1006 Gym Class

题解:

贪心。

分析题,首先想把越大的放越前面,但是有人恨他的话,恨他的人要放在更前面。

再一想,也就是有人恨的人,先不能放,先要放没人恨的人。

再一想,放了没人恨的人,它就不会影响到它恨的人,可以把它恨的人的【被恨次数】减一,它恨的人可能就变成没人恨的人。变成了没人恨的人,就有了加入排队的机会。

所以我们就用一个优先队列这样搞就行了。

(我用的是set,比赛时没想清楚就写了,把有人恨的也丢进set了,后来超时,改了一下才过,写题前的思考与规划需要改进)

代码:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 
 14 #define MZ(array) memset(array, 0, sizeof(array))
 15 #define MF1(array) memset(array, -1, sizeof(array))
 16 #define MINF(array) memset(array, 0x3f, sizeof(array))
 17 #define REP(i,n) for(i=0;i<(n);i++)
 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 19 #define ROF(i,x,y) for(i=(x);i>=(y);i--)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
 24 #define WN(x) printf("%d\n",x);
 25 #define RE  freopen("D.in","r",stdin)
 26 #define WE  freopen("huzhi.txt","w",stdout)
 27 #define MP make_pair
 28 #define PB push_back
 29 #define PF push_front
 30 #define PPF pop_front
 31 #define PPB pop_back
 32 #define lowbit(x) ((x)&(-x))
 33 template<class T>inline void OA(const T &a,const int &st,const int &ed) {
 34     if(ed>=st)cout<<a[st];
 35     int i;
 36     FOR(i,st+1,ed)cout<<' '<<a[i];
 37     puts("");
 38 }
 39 typedef long long LL;
 40 typedef unsigned long long ULL;
 41 const double PI=acos(-1.0);
 42 const double EPS=1e-10;
 43 inline int sgn(double &x) {
 44     if(fabs(x) < EPS)return 0;
 45     if(x < 0)return -1;
 46     else return 1;
 47 }
 48 
 49 const int MAXN=111111;
 50 const int MAXM=33;
 51 
 52 struct Edge {
 53     int y;
 54     int next;
 55 } e[MAXN];
 56 int en;
 57 int head[MAXN];
 58 
 59 inline void addEdge(const int &x,const int &y) {
 60     e[en].y = y;
 61     e[en].next = head[x];
 62     head[x] = en;
 63     en++;
 64 }
 65 
 66 int n,m;
 67 pair<int,int> a[MAXN];
 68 
 69 set<int>st;
 70 set<int>::iterator it;
 71 
 72 inline void del1enemy(const int &x) {
 73     a[x].first--;
 74     if(a[x].first==0)st.insert(a[x].second);
 75 }
 76 
 77 inline LL farm() {
 78     int i,j;
 79     st.clear();
 80     FOR(i,1,n) {
 81         if(a[i].first==0) st.insert(a[i].second);
 82     }
 83     LL re = 0;
 84     int mi = 12345678;
 85     FOR(i,1,n) {
 86         it = st.begin();
 87         int x= (*it);
 88         mi = min(mi, -x);
 89         re+=mi;
 90         st.erase(it);
 91         j = head[-x];
 92         while(j!=-1) {
 93             del1enemy(e[j].y);
 94             j = e[j].next;
 95         }
 96     }
 97     return re;
 98 }
 99 
100 int main() {
101     int i,x,y;
102     int T;
103     RD(T);
104     FOR(i,1,100000){
105         a[i].second = -i;
106     }
107     while(T--) {
108         RD2(n,m);
109         en=0;
110         MF1(head);
111         FOR(i,1,n) {
112             a[i].first=0;
113         }
114         REP(i,m) {
115             RD2(x,y);
116             addEdge(x,y);
117             a[y].first++;
118         }
119         cout<<farm()<<endl;
120     }
121     return 0;
122 }
View Code

 

posted @ 2016-05-23 20:59  带鱼Yuiffy  阅读(341)  评论(0编辑  收藏  举报