2019杭電多校第八場

1004 Acesrc and Hunting

很遺憾由於沒有考慮到nnmm的大小關係導致賽後五分鐘補題。。。
首先構造2k2*k的形式
01234560123456
abcdefgabcdefg
當k是奇數時,順序爲0b2d4g5e6f3c1a0b2d4g5e6f3c1a
0123456701234567
abcdefghabcdefgh
當k是偶數時,順序爲0b2d4f6h57ge3c1a0b2d4f6h57ge3c1a
反正就是互相取,在頂部繞一下就好
這樣繞完之後就從0變到了a,也就是第一行開始,第二行結束
那麼第二組就要第四行開始,第三行結束(對稱)
考慮最後多一行怎麼辦?嘗試構造3k3*k
0123456701234567
abcdefghabcdefgh
xyxxxxxxyxxxxx
xxxxxxxxxxxxxx
xxxxxxxxxxxxxx
假設現在要填最後三行,注意無論在0結束還是在a結束,都可以跳到y處
如果k是奇數,就先放入如下一組:
714714
63(9)63(9)
285285
否則就先放如下一組:
4141
2(6)2(6)
5353
這樣構造的原因是爲了兩種起始狀態的結束點都在正中間(括號處),因此接下來構造若干組:
5252-5252-…
3636-3636-…
1414-1414-…
即可

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
int T,n,m,l,r,tot,num,i,j,x,y,flag;
int f[105][105],g[105][105],res1[10005],res2[10005];
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d",&n,&m);
        if (n > m) {swap(n,m); flag = 1;} else flag = 0;
        if (n == 1 && m == 1) {cout<<"YES"<<endl; cout<<"1 1"<<endl; continue;}
        if (n == 1 || m == 1) {cout<<"NO"<<endl; continue;}
        if (n == 2 && m == 2) {cout<<"NO"<<endl; continue;}
        if (n % 2 == 0) num = n / 2; else num = (n - 3) / 2;
        tot = 0;
        l = 1; r = 2;
        while (num--)
        {
            if (m % 2 == 0)
            {
                fo(i,1,m) if (i % 2 == 1) f[l][i] = ++tot; else f[r][i] = ++tot;
                f[l][m-2] = ++tot; f[l][m] = ++tot;
                f[r][m-1] = ++tot;
                fd(i,m-3,1) if (i % 2 == 1) f[r][i] = ++tot; else f[l][i] = ++tot;
            }    else
            {
                fo(i,1,m-2) if (i % 2 == 1) f[l][i] = ++tot; else f[r][i] = ++tot;
                f[r][m] = ++tot; f[l][m-1] = ++tot; f[r][m-2] = ++tot;
                f[l][m] = ++tot; f[r][m-1] = ++tot;
                fd(i,m-3,1) if (i % 2 == 0) f[l][i] = ++tot; else f[r][i] = ++tot;
            }
            if (l < r) {r += 1; l += 3;} else {l += 1; r += 3;}
        }
        if (n == 3)
        {
            if (m == 3)
            {
                x=1; y=1; f[x][y] = ++tot;
                x+=2; y++; f[x][y] = ++tot;
                x-=2; y++; f[x][y] = ++tot;
                x++; y--; f[x][y] = ++tot;
                x++; y--; f[x][y] = ++tot;
                x-=2; y++; f[x][y] = ++tot;
                x+=2; y++; f[x][y] = ++tot;
                x--; y-=2; f[x][y] = ++tot;
                y+=2; f[x][y] = ++tot;
            }    else
            {
                x=1; y=1; f[x][y] = ++tot;
                x+=2; y++; f[x][y] = ++tot;
                x--; y--; f[x][y] = ++tot;
                x--; y++; f[x][y] = ++tot;
                x+=2; y--; f[x][y] = ++tot;
                x--; y++; f[x][y] = ++tot;
                if (m % 2 == 0) num = m / 2 - 1; else num = (m-3) / 2 - 1;
                while (num--)
                {
                    x++; y++; f[x][y] = ++tot;
                    x-=2; y++; f[x][y] = ++tot;
                    x++; y--; f[x][y] = ++tot;
                    x++; y++; f[x][y] = ++tot;
                    x-=2; y--; f[x][y] = ++tot;
                    x++; y++; f[x][y] = ++tot;
                }
                if (m % 2 == 1)
                {
                    x++; y++; f[x][y] = ++tot;
                    x--; y++; f[x][y] = ++tot;
                    x--; y++; f[x][y] = ++tot;
                    x++; y-=2; f[x][y] = ++tot;
                    x++; y++; f[x][y] = ++tot;
                    x--; y++; f[x][y] = ++tot;
                    x--; y--; f[x][y] = ++tot;
                    x+=2; y++; f[x][y] = ++tot;
                    x-=2; y-=2; f[x][y] = ++tot; 
                }
            }
        }
        if (n != 3 && n % 2 == 1)
        {
            if (m == 3)
            {
                x = n-2; y = 2; f[x][y] = ++tot;
                x+=2; y++; f[x][y] = ++tot;
                x--; y--; f[x][y] = ++tot;
                x--; y--; f[x][y] = ++tot;
                x++; y+=2; f[x][y] = ++tot;
                x++; y--; f[x][y] = ++tot;
                x--; y--; f[x][y] = ++tot;
                x--; y+=2; f[x][y] = ++tot;
                x+=2; y-=2; f[x][y] = ++tot;
            }    else
            {
                f[n-2][2] = ++tot; f[n-1][1] = ++tot; f[n][2] = ++tot;
                f[n-2][1] = ++tot; f[n][1] = ++tot; f[n-1][2] = ++tot;
                if (m % 2 == 0) num = m / 2 - 1; else num = (m-3) / 2 - 1;
                x = n-1; y = 2;
                while (num--)
                {
                    x++; y++; f[x][y] = ++tot;
                    x-=2; y++; f[x][y] = ++tot;
                    x++; y--; f[x][y] = ++tot;
                    x++; y++; f[x][y] = ++tot;
                    x-=2; y--; f[x][y] = ++tot;
                    x++; y++; f[x][y] = ++tot;
                }
                if (m % 2 == 1)
                {
                    x++; y++; f[x][y] = ++tot;
                    x--; y++; f[x][y] = ++tot;
                    x--; y++; f[x][y] = ++tot;
                    x++; y-=2; f[x][y] = ++tot;
                    x++; y++; f[x][y] = ++tot;
                    x--; y++; f[x][y] = ++tot;
                    x--; y--; f[x][y] = ++tot;
                    x+=2; y++; f[x][y] = ++tot;
                    x-=2; y-=2; f[x][y] = ++tot; 
                }
            }    
        }
        fo(i,1,n) fo(j,1,m) g[i][j] = f[i][j];
        if (flag == 1) {fo(i,1,m) fo(j,1,n) f[i][j] = g[j][i]; swap(n,m);}

        cout<<"YES"<<endl;
        fo(i,1,n) fo(j,1,m) res1[f[i][j]] = i,res2[f[i][j]] = j;
        fo(i,1,n*m) printf("%d %d\n",res1[i],res2[i]);
    }
}

1009 Calabash and Landlord

懶得分類討論了,直接座標乘2離散,然後跑dfs

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
int T,k,i,j,res;
int x[5],y[5],g[10],f[30][30];
void dfs(int x,int y)
{
   if (x < 1 || x > 16 || y < 1 || y > 16) return; 
   if (f[x][y] == 0) f[x][y] = 1; else return;
   dfs(x+1,y); dfs(x-1,y); dfs(x,y+1); dfs(x,y-1);
}
int main()
{
   scanf("%d",&T);
   while (T--)
   {
       scanf("%d%d%d%d",&x[1],&y[1],&x[2],&y[2]);
       scanf("%d%d%d%d",&x[3],&y[3],&x[4],&y[4]);
       k = 0;
       fo(i,1,4) g[++k] = x[i];
       fo(i,1,4) g[++k] = y[i];
       sort(g+1,g+8+1);
       k = unique(g+1,g+8+1) - (g+1);
       fo(i,1,4) x[i] = lower_bound(g+1,g+k+1,x[i]) - g;
       fo(i,1,4) y[i] = lower_bound(g+1,g+k+1,y[i]) - g;
       fo(i,1,4) x[i] *= 2,y[i] *= 2;
       fo(i,1,16) fo(j,1,16) f[i][j] = 0;
       fo(i,x[1],x[2]) f[i][y[1]] = f[i][y[2]] = 1;
       fo(i,y[1],y[2]) f[x[1]][i] = f[x[2]][i] = 1;
       fo(i,x[3],x[4]) f[i][y[3]] = f[i][y[4]] = 1;
       fo(i,y[3],y[4]) f[x[3]][i] = f[x[4]][i] = 1;
       res = 0;
       fo(i,1,16) fo(j,1,16) 
       if (f[i][j] == 0)
       {
           res++; dfs(i,j);
       }
       cout<<res<<endl;
   }
}

1010 Quailty and CCPC

如果金牌最後一名是x.5名,就輸出x+1名

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
struct www{char name[100]; int p,t;} f[100005];
int T,n,d,i,rk;
bool cmp(const www &a,const www &b)
{
    if (a.p != b.p) return a.p > b.p; else return a.t < b.t;
}
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d",&n,&d);
        fo(i,1,n) scanf("%s%d%d",f[i].name,&f[i].p,&f[i].t);
        if (n * d % 10 != 5) cout<<"Quailty is very great"<<endl; else
        {
            sort(f+1,f+n+1,cmp);
            rk = n * d / 10 + 1;
            printf("%s\n",f[rk].name);
        }
    }
    return 0;
}

1011 Roundgod and Milk Tea

標算是用二分圖匹配那套理論,我的貪心也不知道對不對。。
按照1~n的順序安排班級,當排第i個班級的時候,優先喝第i+1個班級(感覺就是分配某個班級的時候,如果這個班級的奶茶已經被喝掉了就很穩)
如果喝光了就繼續喝後面班級的奶茶
然後wa了。。(隨便搞一組就被艹掉了)
然後把“要喝的奶茶”從大到小排序就a了(感覺就是儘可能地先多喝奶茶,把大量班級喝光了就比較穩)

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
struct node{int a,b;} f[1000005];
int T,n,i,r,t,flag;
long long res;
bool cmp(const node &x,const node &y) {if (x.a != y.a) return x.a > y.a; else return x.b < y.b;}
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&n);
        fo(i,1,n) scanf("%d%d",&f[i].a,&f[i].b);
        sort(f+1,f+n+1,cmp);
        if (n == 1) {cout<<0<<endl; continue;}
        r = 2; res = 0; flag = 0;
        fo(i,1,n)
        {
            if (r == i) {r++; if (r == n + 1) r = 1;}
            t = f[i].a;
            while (1)
            {
                if (f[r].b >= t) {res += t; f[r].b -= t; break;}
                res += f[r].b; t -= f[r].b; f[r].b = 0; r++;
                if (r == n + 1) r = 1;
                if (r == i) {flag++; break;}
            }
            if (flag == 2) break;
        }
        cout<<res<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章