首页 > ACM题库 > HDU-杭电 > HDU 3437-Garden-线性结构-[解题报告]HOJ
2014
03-23

HDU 3437-Garden-线性结构-[解题报告]HOJ

Garden

问题描述 :

Every giantarum has its garden. So welcome to AekdyCoin’s garden! Here is the spray pond!
Queue-jumpers

The small blue point in the figure above is the headwater. The stream path is red. And there are some kind of dam-board, any of them has magic power! When the water meets with the dam-board, something will happen!
Consider the headwater as one point in three-dimensional space and its coordinate is (0, 0, H). Then a velocity is given as the water’s horizontal velocity. You could see in the figure following:

Queue-jumpers

So if there is no dam-board cut off the stream path, the stream path will just as the yellow path in the figure above!( Air drag, friction will be ignore!)

Queue-jumpers

But if there exist some dam-board cut off the stream path

So, if the dam-board cut off the stream, the Vertical velocity of the stream will become 0! And then depend on the magic power of the dam-board, the New_Vx ,New_Vy of New_V will change!

There are three kind of dam-board in AekdyCoin’s Garden.

(1)  Type 0: the horizontal velocity vector rotate anticlockwise for some radian:

Queue-jumpers

(2)  Type 1: The Vx will be modified!

Queue-jumpers

If the Vx is modified, we could know the horizontal velocity will be modified too!

(3)  Type 2: The Vy will be modified!

Queue-jumpers

If the Vy is modified, we could know the horizontal velocity will be modified too!

Note: The modification happened at the moment when the stream touches the dam-board

Now AekdyCoin focus on a water-drop at the headwater and its mass is exactly M (kg).
Now Stupid AekdyCoin want you to write a program to tell him the time this water-drop need to drop onto the plane (z = 0). (In this problem, the acceleration due to gravity G is 9.18)

输入:

In the first line there is an integer T, indicates the number of test cases. (T <= 10)
In each case, the first line contains three real numbers Vx,Vy and H, indicates the horizontal velocity and the headwater’s three dimensional coordinate is (0,0,H).
(-1000 <= Vx,Vy <= 1000, |H| <= 1000)
Then a single line contains only one integer N, indicates the number of dam-board(0 <= N <= 10)
Then following N lines:
In each line, the first real number h is the height of the dam-board(|h| <= 1000), and then an integer Ni indicates the coordinate of the Ni vertex of the dam-board(3<=Ni<=10). Then Ni coordinate (xi,yi) (-1000<=xi,yi<=1000,xi,yi are both integers)(Dam-board is always on a horizontal plane, so (xi,yi) indicates the three dimensional coordinate of the vertex is (xi,yi,h),and it is convex polygon.All the points will be given in clockwise or anticlockwise order!No two board share the same height!). Then one integer typ indicate the type of the dam-board, at last one real number k:
(1)  If the typ = 0, then the k indicate the radian(|k| <= 2.0 * PI,PI = 3.1415…)
(2)  If typ = 1 or typ = 2 then we should change Vx or Vy into k! (|k| <= 1000)

输出:

In the first line there is an integer T, indicates the number of test cases. (T <= 10)
In each case, the first line contains three real numbers Vx,Vy and H, indicates the horizontal velocity and the headwater’s three dimensional coordinate is (0,0,H).
(-1000 <= Vx,Vy <= 1000, |H| <= 1000)
Then a single line contains only one integer N, indicates the number of dam-board(0 <= N <= 10)
Then following N lines:
In each line, the first real number h is the height of the dam-board(|h| <= 1000), and then an integer Ni indicates the coordinate of the Ni vertex of the dam-board(3<=Ni<=10). Then Ni coordinate (xi,yi) (-1000<=xi,yi<=1000,xi,yi are both integers)(Dam-board is always on a horizontal plane, so (xi,yi) indicates the three dimensional coordinate of the vertex is (xi,yi,h),and it is convex polygon.All the points will be given in clockwise or anticlockwise order!No two board share the same height!). Then one integer typ indicate the type of the dam-board, at last one real number k:
(1)  If the typ = 0, then the k indicate the radian(|k| <= 2.0 * PI,PI = 3.1415…)
(2)  If typ = 1 or typ = 2 then we should change Vx or Vy into k! (|k| <= 1000)

样例输入:

2

1 0 -5
0

1 0 18.36
1 
9.18 4 0 0 100 0 100 100 0 100 0 3.1415927

样例输出:

Case 1: Forever!
Case 2: 4.24


[hint]

In case 1:

Queue-jumpers
In case 2:
Queue-jumpers


地址:http://acm.hdu.edu.cn/showproblem.php?pid=3474
题目大意:
有一个环,找出有多少种方案,从中间减掉一段后可以使其从剪掉的地方顺时钟或逆时针数,c的数量总是大于j的数量。
因为数据要10^6次,数据太大所以用单调队列
无论是从那个点开始找,c的数量比-j的数量最小的点是固定的。
用单调队列从左找到右找到最sum最小的,只要这个点满足,从剪掉的点到,这个点之间的c多余j,那么其他点的c一定大于j。
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#define Maxn 3000000
using namespace std;
int sum[Maxn];
char str2[Maxn], str1[Maxn];
int Q[Maxn];
int num;
bool hash[2][Maxn];
void dqueue(int x, int y, int n, char *s, bool mark) {
    int
tail = 0, head = 1;
    sum[0]
= 0;
    for
(int i = 1; i <= n; i ++) {
   sum[i] = sum[i - 1] + (s[i -
1] == ‘C’ ? 1 : -1);
    }
    for
(int i = 1; i <= y; i ++) {
   int p = i – x;
   while (head <=
tail && sum[p] <
sum[Q[tail]]) {
 tail –;
   }
   Q[++tail] = p;
    }
    for
(int i = y + 1; i <= n + 1; i ++) {
   int p = i – x;
   while (head
<=tail && sum[p]
< sum[Q[tail]]) {
 tail –;
   }
   Q[++tail] = p;
   while (head <
tail && i – Q[head]
> y) {
 head ++;
   }
   hash[mark][p - y] =
(sum[Q[head]] >= sum[p - y]) ;
    }
}
int main()
{
    int
casenumber;
scanf(“%d”, &casenumber);
getchar();
for(int h = 1; h <= casenumber; h ++) {
 num = 0;
 gets(str1);
 int len = strlen(str1);
 strcpy(str2,str1);
 strcat(str2,str1);
 dqueue(1, len, len * 2, str2, 0);
 int N = 2 *len;
 for (int i = 0; i < N; i++)
{
     str1[i] =
str2[N - i - 1];
 }
 str1[N] = 0;
 dqueue(1, len, len * 2,str1, 1);
 for(int i = 0; i < len; i ++)
{
 num+=(hash[0][i] || hash[1][len - i]);
 }
 printf(“Case %d: %d\n”, h,num);
}
    return
0;
}
参考:http://blog.sina.com.cn/s/blog_4c5e203b0100vl45.html


  1. 站长,你好!
    你创办的的网站非常好,为我们学习算法练习编程提供了一个很好的平台,我想给你提个小建议,就是要能把每道题目的难度标出来就好了,这样我们学习起来会有一个循序渐进的过程!

  2. #include <stdio.h>
    int main()
    {
    int n,p,t[100]={1};
    for(int i=1;i<100;i++)
    t =i;
    while(scanf("%d",&n)&&n!=0){
    if(n==1)
    printf("Printing order for 1 pages:nSheet 1, front: Blank, 1n");
    else {
    if(n%4) p=n/4+1;
    else p=n/4;
    int q=4*p;
    printf("Printing order for %d pages:n",n);
    for(int i=0;i<p;i++){
    printf("Sheet %d, front: ",i+1);
    if(q>n) {printf("Blank, %dn",t[2*i+1]);}
    else {printf("%d, %dn",q,t[2*i+1]);}
    q–;//打印表前
    printf("Sheet %d, back : ",i+1);
    if(q>n) {printf("%d, Blankn",t[2*i+2]);}
    else {printf("%d, %dn",t[2*i+2],q);}
    q–;//打印表后
    }
    }
    }
    return 0;
    }