ZOJ Monthly, August 2014

135 - ZOJ Monthly, August 2014

A:构造问题,判断序列奇偶性,很容易发现最小值不是1就是0,最大值不是n就是n - 1,注意细节去构造即可

E:dp,dp[i][j]表示长度i,末尾状态为j的最大值,然后每个位置数字取与不取,不断状态转移即可

G:就一个模拟题没什么好说的

H:dfs,每次dfs下去,把子树宽度保存下来,然后找最大值,如果有多个,就是最大值+cnt宽度

I:构造,如果r * 2 > R,肯定无法构造,剩下的就二分底边,按等腰三角形去构造即可

代码:

A:

 

[cpp]  view plain copy
 
  1. #include <cstdio>  
  2. #include <cstring>  
  3. #include <cmath>  
  4. #include <algorithm>  
  5. using namespace std;  
  6.   
  7. int n;  
  8.   
  9. void print(int n) {  
  10.     if (n == 3) {  
  11.     printf("3 1 2");  
  12.     return;  
  13.     }  
  14.     if (n % 2) {  
  15.     int len = (n - 3) / 2;  
  16.     printf("%d %d", n, n - len);  
  17.     for (int i = n - 1; i > n - len; i--)  
  18.         printf(" %d %d", i, i - len);  
  19.     printf(" 3 1 2");  
  20.     }  
  21.     else {  
  22.     int len = n / 2;  
  23.     printf("%d %d", n, n - len);  
  24.     for (int i = n - 1; i > n - len; i--)  
  25.         printf(" %d %d", i, i - len);  
  26.     }  
  27. }  
  28.   
  29. void print2(int n) {  
  30.     print(n - 2);  
  31.     printf(" %d %d", n - 1, n);  
  32. }  
  33.   
  34. void solve() {  
  35.     if (n == 1) {  
  36.     printf("1 1\n1\n1\n");  
  37.     return;  
  38.     }  
  39.     if (n == 2) {  
  40.     printf("1 1\n1 2\n2 1\n");  
  41.     return;  
  42.     }  
  43.     if (n == 3) {  
  44.     printf("0 2\n3 1 2\n1 2 3\n");  
  45.     return;  
  46.     }  
  47.     if (n % 2 == 0) {  
  48.     if (n / 2 % 2) {  
  49.         printf("1 %d\n", n - 1);  
  50.         print2(n); printf("\n");  
  51.         print2(n - 1);  
  52.         printf(" %d\n", n);  
  53.     }  
  54.     else {  
  55.         printf("0 %d\n", n);  
  56.         print(n); printf("\n");  
  57.         print(n - 1); printf(" %d\n", n);  
  58.     }  
  59.     }  
  60.     else {  
  61.     if ((n + 1) / 2 % 2) {  
  62.         printf("1 %d\n", n);  
  63.         print(n - 2); printf(" %d %d\n", n - 1, n);  
  64.         print(n - 1); printf(" %d\n", n);  
  65.     }  
  66.     else {  
  67.         printf("0 %d\n", n - 1);  
  68.         print(n); printf("\n");  
  69.         print2(n - 1); printf(" %d\n", n);  
  70.     }  
  71.     }  
  72. }  
  73.   
  74. int main() {  
  75.     while (~scanf("%d", &n)) {  
  76.     solve();  
  77.     }  
  78.     return 0;  
  79. }  


E:

 

 

[cpp]  view plain copy
 
  1. #include <cstdio>  
  2. #include <cstring>  
  3. #include <algorithm>  
  4. #include <map>  
  5. using namespace std;  
  6.   
  7. const int INF = 0x3f3f3f3f;  
  8. int t, n;  
  9.   
  10. map<intint> dp[2];  
  11. map<intint>::iterator it;  
  12.   
  13. int lowbit(int x) {  
  14.     return (x&(-x));  
  15. }  
  16.   
  17. int solve() {  
  18.     dp[0].clear();  
  19.     int pre = 1, now = 0;  
  20.     int num;  
  21.     dp[0][0] = 0;  
  22.     for (int i = 0; i < n; i++) {  
  23.     scanf("%d", &num);  
  24.     num /= 2;  
  25.     swap(pre, now);  
  26.     dp[now].clear();  
  27.     for (it = dp[pre].begin(); it != dp[pre].end(); it++) {  
  28.         int s = it->first;  
  29.         if (dp[now].count(s) == 0) dp[now][s] = dp[pre][s];  
  30.         else dp[now][s] = max(dp[now][s], dp[pre][s]);  
  31.         int next;  
  32.         if (s % num) {  
  33.         next = num;  
  34.         if (dp[now].count(next) == 0) dp[now][next] = dp[pre][s] + num * 2;  
  35.         else dp[now][next] = max(dp[now][next], dp[pre][s] + num * 2);  
  36.         }  
  37.         else {  
  38.         next = s + num;  
  39.         int add = (s % lowbit(next) * 2 + num) * 2;  
  40.         if (dp[now].count(next) == 0) dp[now][next] = dp[pre][s] + add;  
  41.         else dp[now][next] = max(dp[now][next], dp[pre][s] + add);  
  42.         }  
  43.     }  
  44.     }  
  45.     int ans = 0;  
  46.     for (it = dp[now].begin(); it != dp[now].end(); it++)  
  47.     ans = max(ans, it->second);  
  48.     return ans;  
  49. }  
  50.   
  51. int main() {  
  52.     scanf("%d", &t);  
  53.     while (t--) {  
  54.     scanf("%d", &n);  
  55.     printf("%d\n", solve());  
  56.     }  
  57.     return 0;  
  58. }  


G:

 

 

[cpp]  view plain copy
 
  1. #include <cstdio>  
  2. #include <cstring>  
  3. #include <vector>  
  4. #include <algorithm>  
  5. using namespace std;  
  6.   
  7. const int N = 55;  
  8. const int d[8][2] = {{1, 0}, {1, 1}, {1, -1}, {0, 1}, {0, -1}, {-1, 0}, {-1, 1}, {-1, -1}};  
  9.   
  10. typedef pair<intint> pii;  
  11.   
  12. int t;  
  13. int n, m, f, k;  
  14. int g[N][N];  
  15. int gg[N][N];  
  16. char str[55];  
  17. vector<pii> go[1005];  
  18.   
  19. void solve() {  
  20.     for (int ti = 1; ti <= f; ti++) {  
  21.     memset(gg, 0, sizeof(gg));  
  22.     for (int i = 1; i <= n; i++) {  
  23.         for (int j = 1; j <= m; j++) {  
  24.         if (g[i][j] == 1) {  
  25.             for (int k = 0; k < 8; k++) {  
  26.             int xx = i + d[k][0];  
  27.             int yy = j + d[k][1];  
  28.             if (xx <= 0 || xx > n || yy <= 0 || yy > m) continue;  
  29.             gg[xx][yy]++;  
  30.             }  
  31.         }  
  32.         }  
  33.     }  
  34.   
  35.     for (int i = 1; i <= n; i++)  
  36.         for (int j = 1; j <= m; j++) {  
  37.         if (g[i][j] == 2) continue;  
  38.         else if (g[i][j] == 0) {  
  39.             if (gg[i][j] == 3) g[i][j] = 1;  
  40.         }  
  41.         else {  
  42.             if (gg[i][j] < 2 || gg[i][j] > 3) g[i][j] = 0;  
  43.         }  
  44.         }  
  45.     for (int i = 0; i < go[ti].size(); i++) {  
  46.         g[go[ti][i].first][go[ti][i].second] = 2;  
  47.     }  
  48.     }  
  49.     for (int i = 1; i <= n; i++) {  
  50.     for (int j = 1; j <= m; j++) {  
  51.         if (g[i][j] == 2) printf("X");  
  52.         else printf("%d", g[i][j]);  
  53.     }  
  54.     printf("\n");  
  55.     }  
  56. }  
  57.   
  58. int main() {  
  59.     scanf("%d", &t);  
  60.     while (t--) {  
  61.     scanf("%d%d%d%d", &n, &m, &f, &k);  
  62.     for (int i = 1; i <= f; i++)  
  63.         go[i].clear();  
  64.     for (int i = 1; i <= n; i++) {  
  65.         scanf("%s", str + 1);  
  66.         for (int j = 1; j <= m; j++) {  
  67.         g[i][j] = str[j] - '0';  
  68.         }  
  69.     }  
  70.     int ti, x, y;  
  71.     while (k--) {  
  72.         scanf("%d%d%d", &ti, &x, &y);  
  73.         go[ti].push_back(make_pair(x, y));  
  74.     }  
  75.     solve();  
  76.     }  
  77.     return 0;  
  78. }  

 

H:

 

[cpp]  view plain copy
 
  1. #include <cstdio>  
  2. #include <cstring>  
  3. #include <vector>  
  4. #include <algorithm>  
  5. using namespace std;  
  6.   
  7. const int N = 10005;  
  8.   
  9. int n;  
  10. vector<int> g[N];  
  11.   
  12. int dfs(int u) {  
  13.     int sz = g[u].size();  
  14.     vector<int> save;  
  15.     for (int i = 0; i < sz; i++)  
  16.     save.push_back(dfs(g[u][i]));  
  17.     sort(save.begin(), save.end());  
  18.     sz = save.size();  
  19.     int cnt = 0;  
  20.     int ans = 1;  
  21.     for (int i = sz - 1; i >= 0; i--) {  
  22.     if (i != sz - 1 && save[i] != save[i + 1]) break;  
  23.     ans = save[i] + cnt;  
  24.     cnt++;  
  25.     }  
  26.     return ans;  
  27. }  
  28.   
  29. int main() {  
  30.     while (~scanf("%d", &n)) {  
  31.     for (int i = 1; i <= n; i++)  
  32.         g[i].clear();  
  33.     int v;  
  34.     for (int i = 2; i <= n; i++) {  
  35.         scanf("%d", &v);  
  36.         g[v].push_back(i);  
  37.     }  
  38.     printf("%d\n", dfs(1));  
  39.     }  
  40.     return 0;  
  41. }  


I:

 

 

[cpp]  view plain copy
 
  1. #include <cstdio>  
  2. #include <cstring>  
  3. #include <cmath>  
  4.   
  5. double r, R;  
  6.   
  7. double h, x;  
  8.   
  9. double cal(double a) {  
  10.     double d = a / 2;  
  11.     h = sqrt(R * R - d * d) + R;  
  12.     x = sqrt(h * h + d * d);  
  13.     return a * x * x / (2 * R * (a + x + x));  
  14. }  
  15.   
  16. void solve() {  
  17.     double lx = 0, rx = sqrt(3.0) * R;  
  18.     double mid;  
  19.     for (int i = 0; i < 1000; i++) {  
  20.     mid = (lx + rx) / 2;  
  21.     double tmp = cal(mid);  
  22.     if (tmp > r) rx = mid;  
  23.     else lx = mid;  
  24.     }  
  25.     cal((lx + rx) / 2);  
  26.     printf("%.10lf %.10lf %.10lf\n", mid, x, x);  
  27. }  
  28.   
  29. int main() {  
  30.     while (~scanf("%lf%lf", &r, &R)) {  
  31.     if (r * 2 > R) printf("NO Solution!\n");  
  32.     else solve();  
  33.     }  
  34.     return 0;  
  35. }  





A Abs Problem http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5330

找规律题,构造出解。copyright@ts

复制代码
 1 #include<cstdio>

 2 int main() {

 3     int n,big,sma,id;

 4     while(~scanf("%d",&n)) {

 5         if(n==1) {

 6             puts("1 1");

 7             puts("1");

 8             puts("1");

 9             continue;

10         }

11         if(n==2) {

12             puts("1 1");

13             puts("1 2");

14             puts("2 1");

15             continue;

16         }

17         if(!((n-3)%4)||!(n%4)) {

18             sma=0;

19         }

20         else {

21             sma=1;

22         }

23         if(sma) {

24             if(n&1) {

25                 big=n;

26                 id=3;

27             }

28             else {

29                 big=n-1;

30                 id=4;

31             }

32         }

33         else {

34             if(n&1) {

35                 big=n-1;

36                 id=1;

37             }

38             else {

39                 big=n;

40                 id=2;

41             }

42         }

43         printf("%d %d\n",sma,big);

44         printf("%d",n);

45         for(int i=n-1;i>=1;i--) {

46             printf(" %d",i);

47         }

48         puts("");

49         if(id==1||id==4) {

50             for(int i=n-3;i>=1;i--) {

51                 printf("%d ",i);

52             }

53             printf("%d %d %d\n",n-2,n-1,n);

54         }

55         else {

56             for(int i=n-1; i>=1; i--) {

57                 printf("%d ",i);

58             }

59             printf("%d\n",n);

60         }

61     }

62     return 0;

63 }
复制代码

 

 

G YY's Minions http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5336

模拟题,怎么说怎么做。

复制代码
 1 #include<cstdio>

 2 #include<algorithm>

 3 using namespace std;

 4 const int M=64;

 5 char op[M];

 6 int mat[2][M][M],n,m,f,k,t;

 7 struct G{

 8     int t,x,y;

 9     friend bool operator <(G a,G b){

10         return a.t<b.t;

11     }

12 }g[M*M];

13 int dx[]={-1,-1,-1,0,0,1,1,1};

14 int dy[]={-1,0,1,-1,1,-1,0,1};

15 int sum(int x,int y,int pre){

16     int res=0;

17     for(int i=0,tx,ty;i<8;i++){

18         tx=x+dx[i];

19         ty=y+dy[i];

20         if(tx>=1&&tx<=n&&ty>=1&&ty<=m){

21             if(mat[pre][tx][ty]&1){

22                 res++;

23             }

24         }

25     }

26     return res;

27 }

28 int change(int pre,int num){

29     if(pre==0){

30         if(num==3) return 1;

31         return 0;

32     }

33     if(num==2||num==3) return 1;

34     return 0;

35 }

36 char tochar(int x){

37     if(x==2) return 'X';

38     return x+'0';

39 }

40 int main(){

41     while(~scanf("%d",&t)){

42         while(t--){

43             scanf("%d%d%d%d",&n,&m,&f,&k);

44             int pre=0,now=1;

45             for(int i=1;i<=n;i++){

46                 scanf("%s",op);

47                 for(int j=0;j<m;j++){

48                     mat[pre][i][j+1]=op[j]-'0';

49                 }

50             }

51             for(int i=0;i<k;i++){

52                 scanf("%d%d%d",&g[i].t,&g[i].x,&g[i].y);

53             }

54             sort(g,g+k);

55             for(int u=1,head=0;u<=f;u++,pre^=1,now^=1){

56                 for(int i=1;i<=n;i++){

57                     for(int j=1;j<=m;j++){

58                         if(mat[pre][i][j]==2){

59                             mat[now][i][j]=2;

60                             continue;

61                         }

62                         int num=sum(i,j,pre);

63                         mat[now][i][j]=change(mat[pre][i][j],num);

64                     }

65                 }

66                 while(head<k&&g[head].t==u){

67                     mat[now][g[head].x][g[head].y]=2;

68                     head++;

69                 }

70             }

71             for(int i=1;i<=n;i++){

72                 for(int j=1;j<=m;j++){

73                     putchar(tochar(mat[pre][i][j]));

74                 }

75                 putchar('\n');

76             }

77         }

78     }

79     return 0;

80 }
复制代码

 

 用vector就不用排序了。

复制代码
 1 #include<cstdio>

 2 #include<vector>

 3 using namespace std;

 4 const int M=64;

 5 char op[M];

 6 int mat[2][M][M],n,m,f,k,t;

 7 struct G{

 8     int x,y;

 9 }p;

10 vector<G> g[M*M];

11 int dx[]={-1,-1,-1,0,0,1,1,1};

12 int dy[]={-1,0,1,-1,1,-1,0,1};

13 int sum(int x,int y,int pre){

14     int res=0;

15     for(int i=0,tx,ty;i<8;i++){

16         tx=x+dx[i];

17         ty=y+dy[i];

18         if(tx>=1&&tx<=n&&ty>=1&&ty<=m){

19             if(mat[pre][tx][ty]&1){

20                 res++;

21             }

22         }

23     }

24     return res;

25 }

26 int change(int pre,int num){

27     if(pre==0){

28         if(num==3) return 1;

29         return 0;

30     }

31     if(num==2||num==3) return 1;

32     return 0;

33 }

34 char tochar(int x){

35     if(x==2) return 'X';

36     return x+'0';

37 }

38 int main(){

39     while(~scanf("%d",&t)){

40         while(t--){

41             scanf("%d%d%d%d",&n,&m,&f,&k);

42             int pre=0,now=1;

43             for(int i=1;i<=n;i++){

44                 scanf("%s",op);

45                 for(int j=0;j<m;j++){

46                     mat[pre][i][j+1]=op[j]-'0';

47                 }

48             }

49             for(int i=1;i<=f;i++){

50                 g[i].clear();

51             }

52             for(int i=0,ti;i<k;i++){

53                 scanf("%d%d%d",&ti,&p.x,&p.y);

54                 g[ti].push_back(p);

55             }

56             for(int u=1,head=0;u<=f;u++,pre^=1,now^=1){

57                 for(int i=1;i<=n;i++){

58                     for(int j=1;j<=m;j++){

59                         if(mat[pre][i][j]==2){

60                             mat[now][i][j]=2;

61                             continue;

62                         }

63                         int num=sum(i,j,pre);

64                         mat[now][i][j]=change(mat[pre][i][j],num);

65                     }

66                 }

67                 int lg=g[u].size();

68                 for(int i=0;i<lg;i++){

69                     mat[now][g[u][i].x][g[u][i].y]=2;

70                 }

71             }

72             for(int i=1;i<=n;i++){

73                 for(int j=1;j<=m;j++){

74                     putchar(tochar(mat[pre][i][j]));

75                 }

76                 putchar('\n');

77             }

78         }

79     }

80     return 0;

81 }
复制代码

 

 

 

H Machine http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5337

树的深搜。邻接表快一些

复制代码
 1 #include<cstdio>

 2 #include<cstring>

 3 #include<vector>

 4 #include<algorithm>

 5 #define mt(a,b) memset(a,b,sizeof(a))

 6 using namespace std;

 7 const int M=10010;

 8 struct G{

 9     struct E{

10         int v,next;

11     }e[M<<1];

12     int le,head[M];

13     void init(){

14         le=0;

15         mt(head,-1);

16     }

17     void add(int u,int v){

18         e[le].v=v;

19         e[le].next=head[u];

20         head[u]=le++;

21     }

22 }g;

23 vector<int> son[M];

24 int dfs(int u,int fa){

25     son[u].clear();

26     for(int i=g.head[u];~i;i=g.e[i].next){

27         int v=g.e[i].v;

28         if(v!=fa){

29             son[u].push_back(dfs(v,u));

30         }

31     }

32     sort(son[u].begin(),son[u].end());

33     int res=1,ls=son[u].size();

34     for(int i=0;i<ls;i++){

35         res=max(res,son[u][i]+ls-i-1);

36     }

37     return res;

38 }

39 int main(){

40     int n;

41     while(~scanf("%d",&n)){

42         g.init();

43         for(int v=2,u;v<=n;v++){

44             scanf("%d",&u);

45             g.add(u,v);

46             g.add(v,u);

47         }

48         printf("%d\n",dfs(1,-1));

49     }

50     return 0;

51 }
复制代码

 vector慢一些

复制代码
 1 #include<cstdio>

 2 #include<vector>

 3 #include<algorithm>

 4 using namespace std;

 5 const int M=10010;

 6 vector<int> g[M],son[M];

 7 int dfs(int u,int fa){

 8     son[u].clear();

 9     int lu=g[u].size();

10     for(int i=0;i<lu;i++){

11         int v=g[u][i];

12         if(v!=fa){

13             son[u].push_back(dfs(v,u));

14         }

15     }

16     sort(son[u].begin(),son[u].end());

17     int res=1,ls=son[u].size();

18     for(int i=0;i<ls;i++){

19         res=max(res,son[u][i]+ls-i-1);

20     }

21     return res;

22 }

23 int main(){

24     int n;

25     while(~scanf("%d",&n)){

26         for(int i=1;i<=n;i++){

27             g[i].clear();

28         }

29         for(int v=2,u;v<=n;v++){

30             scanf("%d",&u);

31             g[u].push_back(v);

32             g[v].push_back(u);

33         }

34         printf("%d\n",dfs(1,-1));

35     }

36     return 0;

37 }
复制代码

 

 

I Incircle and Circumcircle http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5338

机智的用不对的三分过了。定义圆都在y轴,定义三角形一个点在圆心,定义三角形是等腰的。

复制代码
 1 #include<cstdio>

 2 #include<cmath>

 3 const double eps=1e-10;

 4 double r,R;

 5 double f(double y) {

 6     double Y=2*R*(1-(r*r)/(y*y));

 7     return fabs(Y-y-r);

 8 }

 9 double TernarySearch(double L,double R) { // 三分查找

10     while(R-L>eps) {

11         double LL=(L*2+R)/3;

12         double RR=(L+R*2)/3;

13         if(f(LL)<f(RR))  //f为对应的值  这里求最小值

14             R=RR;

15         else

16             L=LL;

17     }

18     return L;

19 }

20 int main(){

21     int t1,t2;

22     while(~scanf("%d%d",&t1,&t2)){

23         if(t1*2>t2){

24             puts("NO Solution!");

25             continue;

26         }

27         r=t1;

28         R=t2;

29         double ansy=TernarySearch(r,R+R-r);

30         ansy+=r;

31         double tmp=ansy-r;

32         double sinxita=r/tmp;

33         double cosxita=sqrt(tmp*tmp-r*r)/tmp;

34         double a=ansy*tmp/sqrt(tmp*tmp-r*r);

35         double b=a;

36         double c=2*a*r/tmp;

37         printf("%.18f %.18f %.18f\n",a,b,c);

38     }

39     return 0;

40 }
复制代码

 

 

 


 

你可能感兴趣的:(ZOJ)