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:
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- using namespace std;
- int n;
- void print(int n) {
- if (n == 3) {
- printf("3 1 2");
- return;
- }
- if (n % 2) {
- int len = (n - 3) / 2;
- printf("%d %d", n, n - len);
- for (int i = n - 1; i > n - len; i--)
- printf(" %d %d", i, i - len);
- printf(" 3 1 2");
- }
- else {
- int len = n / 2;
- printf("%d %d", n, n - len);
- for (int i = n - 1; i > n - len; i--)
- printf(" %d %d", i, i - len);
- }
- }
- void print2(int n) {
- print(n - 2);
- printf(" %d %d", n - 1, n);
- }
- void solve() {
- if (n == 1) {
- printf("1 1\n1\n1\n");
- return;
- }
- if (n == 2) {
- printf("1 1\n1 2\n2 1\n");
- return;
- }
- if (n == 3) {
- printf("0 2\n3 1 2\n1 2 3\n");
- return;
- }
- if (n % 2 == 0) {
- if (n / 2 % 2) {
- printf("1 %d\n", n - 1);
- print2(n); printf("\n");
- print2(n - 1);
- printf(" %d\n", n);
- }
- else {
- printf("0 %d\n", n);
- print(n); printf("\n");
- print(n - 1); printf(" %d\n", n);
- }
- }
- else {
- if ((n + 1) / 2 % 2) {
- printf("1 %d\n", n);
- print(n - 2); printf(" %d %d\n", n - 1, n);
- print(n - 1); printf(" %d\n", n);
- }
- else {
- printf("0 %d\n", n - 1);
- print(n); printf("\n");
- print2(n - 1); printf(" %d\n", n);
- }
- }
- }
- int main() {
- while (~scanf("%d", &n)) {
- solve();
- }
- return 0;
- }
E:
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <map>
- using namespace std;
- const int INF = 0x3f3f3f3f;
- int t, n;
- map<int, int> dp[2];
- map<int, int>::iterator it;
- int lowbit(int x) {
- return (x&(-x));
- }
- int solve() {
- dp[0].clear();
- int pre = 1, now = 0;
- int num;
- dp[0][0] = 0;
- for (int i = 0; i < n; i++) {
- scanf("%d", &num);
- num /= 2;
- swap(pre, now);
- dp[now].clear();
- for (it = dp[pre].begin(); it != dp[pre].end(); it++) {
- int s = it->first;
- if (dp[now].count(s) == 0) dp[now][s] = dp[pre][s];
- else dp[now][s] = max(dp[now][s], dp[pre][s]);
- int next;
- if (s % num) {
- next = num;
- if (dp[now].count(next) == 0) dp[now][next] = dp[pre][s] + num * 2;
- else dp[now][next] = max(dp[now][next], dp[pre][s] + num * 2);
- }
- else {
- next = s + num;
- int add = (s % lowbit(next) * 2 + num) * 2;
- if (dp[now].count(next) == 0) dp[now][next] = dp[pre][s] + add;
- else dp[now][next] = max(dp[now][next], dp[pre][s] + add);
- }
- }
- }
- int ans = 0;
- for (it = dp[now].begin(); it != dp[now].end(); it++)
- ans = max(ans, it->second);
- return ans;
- }
- int main() {
- scanf("%d", &t);
- while (t--) {
- scanf("%d", &n);
- printf("%d\n", solve());
- }
- return 0;
- }
G:
- #include <cstdio>
- #include <cstring>
- #include <vector>
- #include <algorithm>
- using namespace std;
- const int N = 55;
- const int d[8][2] = {{1, 0}, {1, 1}, {1, -1}, {0, 1}, {0, -1}, {-1, 0}, {-1, 1}, {-1, -1}};
- typedef pair<int, int> pii;
- int t;
- int n, m, f, k;
- int g[N][N];
- int gg[N][N];
- char str[55];
- vector<pii> go[1005];
- void solve() {
- for (int ti = 1; ti <= f; ti++) {
- memset(gg, 0, sizeof(gg));
- for (int i = 1; i <= n; i++) {
- for (int j = 1; j <= m; j++) {
- if (g[i][j] == 1) {
- for (int k = 0; k < 8; k++) {
- int xx = i + d[k][0];
- int yy = j + d[k][1];
- if (xx <= 0 || xx > n || yy <= 0 || yy > m) continue;
- gg[xx][yy]++;
- }
- }
- }
- }
- for (int i = 1; i <= n; i++)
- for (int j = 1; j <= m; j++) {
- if (g[i][j] == 2) continue;
- else if (g[i][j] == 0) {
- if (gg[i][j] == 3) g[i][j] = 1;
- }
- else {
- if (gg[i][j] < 2 || gg[i][j] > 3) g[i][j] = 0;
- }
- }
- for (int i = 0; i < go[ti].size(); i++) {
- g[go[ti][i].first][go[ti][i].second] = 2;
- }
- }
- for (int i = 1; i <= n; i++) {
- for (int j = 1; j <= m; j++) {
- if (g[i][j] == 2) printf("X");
- else printf("%d", g[i][j]);
- }
- printf("\n");
- }
- }
- int main() {
- scanf("%d", &t);
- while (t--) {
- scanf("%d%d%d%d", &n, &m, &f, &k);
- for (int i = 1; i <= f; i++)
- go[i].clear();
- for (int i = 1; i <= n; i++) {
- scanf("%s", str + 1);
- for (int j = 1; j <= m; j++) {
- g[i][j] = str[j] - '0';
- }
- }
- int ti, x, y;
- while (k--) {
- scanf("%d%d%d", &ti, &x, &y);
- go[ti].push_back(make_pair(x, y));
- }
- solve();
- }
- return 0;
- }
H:
- #include <cstdio>
- #include <cstring>
- #include <vector>
- #include <algorithm>
- using namespace std;
- const int N = 10005;
- int n;
- vector<int> g[N];
- int dfs(int u) {
- int sz = g[u].size();
- vector<int> save;
- for (int i = 0; i < sz; i++)
- save.push_back(dfs(g[u][i]));
- sort(save.begin(), save.end());
- sz = save.size();
- int cnt = 0;
- int ans = 1;
- for (int i = sz - 1; i >= 0; i--) {
- if (i != sz - 1 && save[i] != save[i + 1]) break;
- ans = save[i] + cnt;
- cnt++;
- }
- return ans;
- }
- int main() {
- while (~scanf("%d", &n)) {
- for (int i = 1; i <= n; i++)
- g[i].clear();
- int v;
- for (int i = 2; i <= n; i++) {
- scanf("%d", &v);
- g[v].push_back(i);
- }
- printf("%d\n", dfs(1));
- }
- return 0;
- }
I:
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- double r, R;
- double h, x;
- double cal(double a) {
- double d = a / 2;
- h = sqrt(R * R - d * d) + R;
- x = sqrt(h * h + d * d);
- return a * x * x / (2 * R * (a + x + x));
- }
- void solve() {
- double lx = 0, rx = sqrt(3.0) * R;
- double mid;
- for (int i = 0; i < 1000; i++) {
- mid = (lx + rx) / 2;
- double tmp = cal(mid);
- if (tmp > r) rx = mid;
- else lx = mid;
- }
- cal((lx + rx) / 2);
- printf("%.10lf %.10lf %.10lf\n", mid, x, x);
- }
- int main() {
- while (~scanf("%lf%lf", &r, &R)) {
- if (r * 2 > R) printf("NO Solution!\n");
- else solve();
- }
- return 0;
- }
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 }