1002

1003 Clockwise or Counterclockwise

链接:http://acm.hdu.edu.cn/showproblem.php?pid=6857
题意
给定ABC三个点的坐标,他们一定能构成一个以原点为圆心的圆,问从A->B->C是顺时针还是逆时针
题解
根据右手定则,我们可以知道当以同一个点为顶点的两个矢量叉乘若为正(法向量垂直纸面朝里)则是顺时针,为负(朝外)逆时针即:BAxBC
注意
后面的坐标减去前面的坐标
代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){

    int t;scanf("%d",&t);
    ll ax,ay,bx,by,cx,cy,x1,y1,x2,y2;
    while(t--){
            cin>>ax>>ay>>bx>>by>>cx>>cy;
            x1=ax-cx;y1=ay-cy;
            x2=ax-bx;y2=ay-by;
            if((x1*y2-x2*y1) > 0)printf("Clockwise\n") ;
            else printf("Counterclockwise\n") ;

    }
    return 0 ;
}

1006 Fluctuation Limit

链接:http://acm.hdu.edu.cn/showproblem.php?pid=6860
题意
给定n个区间,然后给定一个升降的最大值k,然后问n个数,他们都在区间内,且两两差小于k
题解
先求出满足这个限制范围的区间,就是从最后一个往前走,使得前面的区间都能够到达后面的区间,取个交集,然后遍历,如果在当前区间内就不动,否则的话就动
注意
前面的想法也想到了,就是后面遍历的时候总担心会两两之间出现问题,就没敢往下写,以后一定要随便莽,呼呼呼~
代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
struct node{
    int l,r;
}Node[maxn];
int main()
{
    int t,n,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)scanf("%d%d",&Node[i].l,&Node[i].r);
        bool ok=true;
        for(int i=n-1;i>=1;i--)
        {
            int tl=Node[i+1].l-k;//从后往前遍历
            int tr=Node[i+1].r+k;
            if(tl>Node[i].r||tr<Node[i].l)
            {
                ok=false;//提前夭折
                break;//直接退出
            }
            Node[i].l=max(tl,Node[i].l);
            Node[i].r=min(tr,Node[i].r);//得到交集
        }
        if(!ok){printf("NO\n");}
        else {
            printf("YES\n");
            int now=Node[1].l;
            printf("%d ",now);
            for(int i=2;i<=n;i++)
            {
                if(now<Node[i].l)now=Node[i].l;
                else if(now>Node[i].r)now=Node[i].r;
                printf("%d ",now);
            }
            printf("\n");
        }
    }
    return 0;
}

1008 Hexagon

链接:http://acm.hdu.edu.cn/showproblem.php?pid=6862
题意
给定一个半径为n由单位六边形的一个多边形,标记了六个方向,问如何走能够走遍这个多边形的每一个小六边形,输出方向
题解
观察到它每次都会有重复,先让它转一圈,发现一圈下来,半径减少了2,而他的规律大概是 xyxyxy...x(表示一个方向)里面的循环个数是n-2,那把所有的方向都找出来,31 42 53 64 15 /26(这个地方快要结尾了,所有tot-1) 3结束一层。
那么重复就好了,再预处理n=2,n=3就好了
注意
起点是最左边的最上面的那个点
代码

#include<bits/stdc++.h>
using namespace std;
vector<int>G[1000];
void init()
{
    G[2].emplace_back(2);
    G[2].emplace_back(3);
    G[2].emplace_back(4);
    G[2].emplace_back(5);
    G[2].emplace_back(6);
    G[2].emplace_back(2);

    G[3].emplace_back(2);
    G[3].emplace_back(3);
    G[3].emplace_back(1);
    G[3].emplace_back(3);
    G[3].emplace_back(4);
    G[3].emplace_back(2);
    G[3].emplace_back(4);
    G[3].emplace_back(5);
    G[3].emplace_back(3);
    G[3].emplace_back(5);
    G[3].emplace_back(6);
    G[3].emplace_back(4);
    G[3].emplace_back(6);
    G[3].emplace_back(1);
    G[3].emplace_back(5);
    G[3].emplace_back(1);
    G[3].emplace_back(2);
    G[3].emplace_back(3);
}
int main()
{
    int t,n,tot;
    cin>>t;
    init();//先把2,3的预处理
    while(t--)
    {
        scanf("%d",&n);
        while(n>1)
        {
            if(G[n].size()==0)//往前迭代
            {
                tot=n-2;//开始重复
                G[n].emplace_back(2);
                for(int i=1;i<=tot;i++){G[n].emplace_back(3);G[n].emplace_back(1);}G[n].emplace_back(3);//后面的是回溯
                for(int i=1;i<=tot;i++){G[n].emplace_back(4);G[n].emplace_back(2);}G[n].emplace_back(4);
                for(int i=1;i<=tot;i++){G[n].emplace_back(5);G[n].emplace_back(3);}G[n].emplace_back(5);
                for(int i=1;i<=tot;i++){G[n].emplace_back(6);G[n].emplace_back(4);}G[n].emplace_back(6);
                for(int i=1;i<=tot;i++){G[n].emplace_back(1);G[n].emplace_back(5);}G[n].emplace_back(1);
                tot--;
                for(int i=1;i<=tot;i++){G[n].emplace_back(2);G[n].emplace_back(6);}G[n].emplace_back(2);

                G[n].emplace_back(3);
                for(auto it:G[n])printf("%d",it);
            }
            else {for(auto it:G[n])printf("%d",it);}
            n-=2;//每次操作完操作半径都减少了两个
        }
        printf("\n");
    }
    return 0;
}

1009