UVALive-7267/UVALive-7261/UVALive-7269/UVALive-7263

UVALive-7267

题意:
给出4个矩形,问你是否用三个矩形组成一个新矩形
思路:
要么就是三个矩形存在一条相同的边
要么就是两个矩形有相同边然后贴在一起组成新边去贴另一个矩形的一条边

//#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long LL;
#define mem(a, b) memset(a, b, sizeof(a))

struct asd{
    int w, h;
}node[5];


bool jud(int x, int y, int z){
    if(node[x].w == node[y].w) if(node[x].w == node[z].h || node[x].w == node[z].w) return true;
    if(node[x].w == node[y].h) if(node[x].w == node[z].h || node[x].w == node[z].w) return true;
    if(node[x].h == node[y].w) if(node[x].h == node[z].h || node[x].h == node[z].w) return true;
    if(node[x].h == node[y].h) if(node[x].h == node[z].h || node[x].h == node[z].w) return true;

    if(node[x].h == node[y].h){
        if(node[z].h == node[x].w + node[y].w) return true;
        if(node[z].w == node[x].w + node[y].w) return true;
    }
    if(node[x].w == node[y].w){
        if(node[z].h == node[x].h + node[y].h) return true;
        if(node[z].w == node[x].h + node[y].h) return true;
    }
    if(node[x].h == node[y].w){
        if(node[z].h == node[x].w + node[y].h) return true;
        if(node[z].w == node[x].w + node[y].h) return true;
    }
    if(node[x].w == node[y].h){
        if(node[z].h == node[x].h + node[y].w) return true;
        if(node[z].w == node[x].h + node[y].w) return true;
    }
    return false;
}

bool solve(){
    for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++)
            for(int k=1;k<=4;k++){
                if(i != j && i != k && j != k){
                    if(jud(i, j, k)) return true;
                }
            }
    return false;
}

int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        for(int i=1;i<=4;i++) scanf("%d%d", &node[i].w, &node[i].h);
        if(solve()) puts("Yes");
        else puts("No");
    }
    return 0;
}

/*
1000
1 5 1 3 2 4 3 5

1 5 1 3 2 4 3 4

3 2 3 2 2 3 1 1

3 2 2 3 6 1 1 1

*/

UVALive-7261

题意:
给出矩形的左上点,宽,高,然后让你去找一个x=n的位置切割,
保证左边面积和右边的差值最小,
在保证以后,要满足左边面积>=右边面积,这个位置是到达的最右位置。
思路:
做两次二分,第一次二分出这个差值最小的最左位置,
第二次二分找这个满足位置的最右。

//#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long LL;
#define mem(a, b) memset(a, b, sizeof(a))

struct asd{
    LL x, y;
    LL w, h;
}node[10010];
int n;
LL RR;

LL cas_Left(LL pos){
    LL ll, rr;
    ll = rr = 0;
    for(int i=0;i<n;i++){
        if(node[i].x+node[i].w <= pos){
            ll += node[i].w*node[i].h;
        }
        else if(node[i].x >= pos){
            rr += node[i].w*node[i].h;
        }
        else{
            ll += node[i].h*(pos-node[i].x);
            rr += node[i].h*(node[i].x+node[i].w-pos);
        }
    }
    return ll-rr;
}

void solve(){
    LL Left = 0, Right = RR;
    while(Left < Right){
//        puts("aaa");
        LL mid = Left + (Right - Left) / 2;
        if(cas_Left(mid) >= 0) Right = mid;
        else Left = mid + 1;
    }
    LL L = Left, R = RR;
    LL tp = cas_Left(Left);
    while(L < R){
        LL mid = L + (R - L + 1) / 2;
        if(cas_Left(mid) == tp) L = mid;
        else R = mid - 1;
    }
    printf("%lld\n", L);
}

int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d%lld", &RR, &n);
        for(int i=0;i<n;i++)
            scanf("%lld%lld%lld%lld", &node[i].x, &node[i].y, &node[i].w, &node[i].h);
//        printf("%lld\n", cas_Left(2));
        solve();
    }
    return 0;
}
/*
1000
1000
2
3 3 1 1
1 1 1 3
*/

UVALive-7269

题意:
每一个相同数字构成一条蛇,所以这串数有头有尾,不会构成环
要求偶数除2有偶数个夹角,奇数除1有奇数个折角。
思路:
无论N奇数还是偶数
奇数就是这么构造:
1357
3357
5557
7777
如果N是偶数:
比如N=8
1357
3357
5557
7777
然后构造偶数就是先竖着构造,然后横着
135788666
335788666
555788442
777788442
对于N为奇数相反,先是横着构造,然后竖着。
要注意,每条蛇是按照顺序输出的。

//#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long LL;
#define mem(a, b) memset(a, b, sizeof(a))

vector<pair<int, int> >po[510];
int ma[550][550];
int main(){
    int n;
    while(~scanf("%d", &n)){
        for(int i=1;i<=n;i++) po[i].clear();
        int x,y;
        if(n % 2 == 0){
            x = n/2;
            y = n+1;
            int p=1, tp;
            for(int i=1;i<=n;i+=2,p++){
                tp = 1;
                while(tp <= p){
                    po[i].push_back(make_pair(p, tp));
                    tp++;
                }
                tp = p-1;
                while(tp >= 1){
                    po[i].push_back(make_pair(tp, p));
                    tp--;
                }
            }
            int op = 1; //heng xian
            int qx =  1, qy = x+1;
            for(tp=n; tp>=2; tp-=2 , op = !op )
            {
                    int tx = qx;
                    int ty = qy;
//                    printf("%d %d\n",qx,qy);
                if(!op){
                    for(; ty <= y; ty++)
                        po[tp].push_back(make_pair(tx,ty));
                    tx++;
                    ty = y;
                    for(; ty >= qy; ty--)
                        po[tp].push_back(make_pair(tx,ty));
                    qx+=2;
                }
                else{
                    for(; tx <= x; tx++)
                        po[tp].push_back(make_pair(tx,ty));
                    ty++;
                    tx = x;
                    for(; tx >= qx; tx--)
                        po[tp].push_back(make_pair(tx,ty));
                    qy+=2;
                }
            }
        }
        else{
            x = (n+1)/2;
            y = n;
            int p=1, tp;
            for(int i=1;i<=n;i+=2,p++){
                tp = 1;
                while(tp <= p){
                    po[i].push_back(make_pair(p, tp));
                    tp++;
                }
                tp = p-1;
                while(tp >= 1){
                    po[i].push_back(make_pair(tp, p));
                    tp--;
                }
            }

            int op = 0; //
            int qx = 1, qy = x+1;
            for(tp=n-1; tp>=2; tp-=2 , op = !op )
            {
                    int tx = qx;
                    int ty = qy;
//                    printf("%d %d\n",qx,qy);
                if(!op){
                    for(; ty <= y; ty++)
                        po[tp].push_back(make_pair(tx,ty));
                    tx++;
                    ty = y;
                    for(; ty >= qy; ty--)
                        po[tp].push_back(make_pair(tx,ty));
                    qx+=2;
                }
                else{
                    for(; tx <= x; tx++)
                        po[tp].push_back(make_pair(tx,ty));
                    ty++;
                    tx = x;
                    for(; tx >= qx; tx--)
                        po[tp].push_back(make_pair(tx,ty));
                    qy+=2;
                }
            }
        }
        printf("%d %d\n", x, y);
        for(int i=1;i<=n;i++){
            int sz = (int)po[i].size();
            for(int j=0;j<sz;j++){
                if(j) printf(" ");
                ma[po[i][j].first][po[i][j].second] = i;
                printf("%d %d", po[i][j].first, po[i][j].second);
            }
            puts("");
        }
//        for(int i=1;i<=x;i++){
//            for(int j=1;j<=y;j++)
//                printf("%3d ",ma[i][j]);
//            puts("");
//        }
    }
    return 0;
}

UVALive-7263

1.进行改变一种的操作比改变一个的操作更优
然后预处理123456变成其他所有种类的最少步数(通过改变一种),可以用bfs
很久没写BFS,突然还给忘了怎么玩的,比如123456->223456是走一步!走一步!然后每次对于一个状态会走30步吧.
最后总处理就可以暴力所有的目标状态,搞出对应位上的改变的串,然后和目标串再对比,加上不同的个数. 每次取小

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章