您的位置:首页 > 其它

SDKD Summer Team Contest X ACM/ICPC 14 北京站现场赛

2015-08-31 21:13 435 查看
//话说今天又有场上看题解的, 真TMD的恶心;

A:水题, 不必多说;

B:其实是可以构造的, 这个题场上没出

1、颜色排序, 按最多, 最少, 次多, 次少填入。

另外, 先奇数,不行再偶数;

队友后来补的

构造:

#include<bits/stdc++.h>
using namespace std;
int num[60];
struct xx{
    int ID,num;
    bool operator <(const xx&rhs) const {
        return num>rhs.num;
    }
}Y[60],YY[60];
int YYY[60];
int a[30][30];
int main()
{
    int t,kase=0;scanf("%d",&t);
    while(t--){
            memset(a,-1,sizeof(a));
        memset(Y,0,sizeof(Y));
        memset(YY,0,sizeof(YY));
        int n,m,k;scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++) { scanf("%d",&Y[i].num); Y[i].ID=i; }
        sort(Y,Y+k);
//        printf("####:");
//        for(int i=0;i<k;i++) printf("%d ",Y[i].num); printf("\n");
        int y1=0,y2=k-1;//printf("***:");
        for(int i=0;i<k;i++)
        {
            if(i%2==0)
            YY[i]=Y[y1++];
            else YY[i]=Y[y2--];
            //printf("%d ",YY[i].num);
            //printf("ID[%d] ",YY[i].ID);
        }//printf("\n");
        int J=0;
        for(int i=0;i<k;i++) {
            while(YY[i].num--)
            YYY[J++] = YY[i].ID;}
//        printf("YYYY:");
//        for(int i=0;i<n*m;i++) printf("%d ",YYY[i]); printf("\n");
        int K=0;
        for(int i=0;i<n;i++){
            if( !( i&1)  )
           {
               for(int j=0;j<m;j+=2)  a[i][j]=YYY[K++];
           }
            else
            { for(int j=1;j<m;j+=2)  a[i][j]=YYY[K++]; }
        }

        for(int i=0;i<n;i++){
        for(int j=0;j<m;j++)
       {

           if(a[i][j]==-1){
            a[i][j]=YYY[K++];
           }
       }
        }

        int flag=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                {

                    if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
                    if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
                    if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
                    if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
                }
                if(flag==0 ) break;
            }
            if(flag==0){
                    memset(a,-1,sizeof(a));
                flag=1;
                int K=0;
        for(int i=0;i<n;i++){
            if( !( i&1)  )
           {
               for(int j=1;j<m;j+=2)  a[i][j]=YYY[K++];
           }
            else
            { for(int j=0;j<m;j+=2)  a[i][j]=YYY[K++]; }
        }

        for(int i=0;i<n;i++){
        for(int j=0;j<m;j++)
       {

           if(a[i][j]==-1){
            a[i][j]=YYY[K++];
           }
       }
        }

         flag=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                {

                    if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
                    if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
                    if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
                    if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
                }
                if(flag==0 ) break;
            }

            }
            if(flag==0&&0){
                    memset(a,-1,sizeof(a));
                flag=1;
                int K=0;
        for(int j=0;j<m;j++){
            if( !( j&1)  )
           {
               for(int i=1;i<n;i+=2)  a[i][j]=YYY[K++];
           }
            else
            { for(int i=0;i<n;i+=2)  a[i][j]=YYY[K++]; }
        }

        for(int j=0;j<m;j++){
        for(int i=0;i<n;i++)
       {

           if(a[i][j]==-1){
            a[i][j]=YYY[K++];
           }
       }
        }

         flag=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                {

                    if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
                    if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
                    if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
                    if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
                }
                if(flag==0 ) break;
            }

            }
            if(flag==0&&0){
                    memset(a,-1,sizeof(a));
                flag=1;
                int K=0;
        for(int j=0;j<m;j++){
            if( !( j&1)  )
           {
               for(int i=0;i<n;i+=2)  a[i][j]=YYY[K++];
           }
            else
            { for(int i=1;i<n;i+=2)  a[i][j]=YYY[K++]; }
        }

        for(int j=0;j<m;j++){
        for(int i=0;i<n;i++)
       {

           if(a[i][j]==-1){
            a[i][j]=YYY[K++];
           }
       }
        }

         flag=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                {

                    if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
                    if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
                    if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
                    if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
                }
                if(flag==0 ) break;
            }

            }
            printf("Case #%d:\n",++kase);
            if(flag) {
                printf("YES\n");
//                printf("^^^^^^\n");
             for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                        if(j==0)
                 printf("%d",a[i][j]+1);
                else printf(" %d",a[i][j]+1);
                }
                printf("\n");
                }
//                printf("^^^^^^\n");
            }
            else printf("NO\n");

    }
    return 0;
}


2、dfs回溯+剪枝;

我当时没想到这个剪枝, 就一直在想构造了;

剪枝还是应该由她的这个主要性质决定的吧;

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 5 + 5;
int res[maxn][maxn];
int cnt[maxn * maxn];
int n, m, k;
int flog;
int ok(int i, int j, int kk)
{
    if(i-1 >= 1)
        if(res[i-1][j] != -1 && res[i-1][j] == kk) return 0;
    if(i+1 <= n)
        if(res[i+1][j] != -1 && res[i+1][j] == kk) return 0;
    if(j-1 >= 1)
        if(res[i][j-1] != -1 && res[i][j-1] == kk) return 0;
    if(j+1 <= m)
        if(res[i][j+1] != -1 && res[i][j+1] == kk) return 0;
    return 1;
}
void dfs(int i, int j, int v)
{
    if(i==n && j==m) flog = true;
    if(flog) return ;
    for(int i = 1; i <= k; ++i)
        if((v+1)/2 < cnt[i]) return ;
    for(int kk = 1; kk <= k; ++kk)
    {
        if(!cnt[kk]) continue;
        if(j==m)
        {
            if(ok(i+1, 1, kk))
            {
                --cnt[kk];
                res[i+1][1] = kk;
                dfs(i+1, 1, v-1);
                if(flog) return ;
                res[i+1][1] = -1;
                ++cnt[kk];
            }
        }
        else
        {
            if(ok(i, j+1, kk))
            {
                --cnt[kk];
                res[i][j+1] = kk;
                dfs(i, j+1, v-1);
                if(flog) return ;
                res[i][j+1] = -1;
                ++cnt[kk];
            }
        }
    }
    return ;
}
int main()
{
    int T;
    scanf("%d", &T);
    int kase = 0;
    while(T--)
    {
        printf("Case #%d:\n", ++kase);
        scanf("%d%d%d", &n, &m, &k);
        memset(cnt,0,sizeof(cnt));
        memset(res,-1,sizeof(res));
        for(int i = 1; i <= k; ++i) scanf("%d", &cnt[i]);
        flog = false;
        dfs(1, 0, n*m);
        if(flog)
        {
            cout << "YES" << endl;
            for(int i = 1; i <= n; ++i)
            {
                for(int j = 1; j <= m; ++j)
                {
                    if(j==1) printf("%d", res[i][j]);
                    else printf(" %d", res[i][j]);
                }
                printf("\n");
            }
        }
        else cout << "NO" << endl;
    }
    return 0;
}
H:队友补的dp

#include<bits/stdc++.h>
using namespace std;
long long dp[3][1100000];
int main()
{
    int T;
    cin>>T;
    int kase=0;
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        int n, m;
        cin>>n>>m;
        int a[50];
        for(int i=1;i<=n;i++)
            cin>>a[i];
            dp[0][0]=1;
        for(int i=1;i<=n;i++)
            for(int j=0;j<1000000;j++)
                dp[i%2][j]=dp[(i-1)%2][j]+dp[(i-1)%2][j^a[i]];
        long long sum=0;
        for(int i=m;i<1000000;i++)
            sum+=dp[n%2][i];
        cout<<"Case #"<<++kase<<": ";
        printf("%I64d\n",sum);
    }
    return 0;
}
I:几何模板

#include<bits/stdc++.h>
using namespace std;

const double eps=1e-8, Pi=acos(-1.0);
struct Point{
    double x, y;
    Point (double _x=0, double _y=0)
    {
        x=_x;
        y=_y;
    }
    Point operator-(const Point &ne) const{
        return Point (x-ne.x,y-ne.y);
    }
};
struct circle
{
    Point o;
    double r;
    circle (){}
    circle(Point _o, double _r)
    {
        o=_o;
        r=_r;
    }
};
inline double dmult(Point a, Point b)
{
    return a.x*b.x+a.y*b.y;
}
inline double lenth(Point a)
{
    return sqrt(dmult(a,a));
}
inline double dist (Point a, Point b)
{
    return lenth(b-a);
}
double area(circle a, circle b)
{
    double d=dist(a.o,b.o), r1=a.r, r2=b.r, r;
    if(r1+r2<=d)
        return 0.0;
    else if(fabs(r1-r2)>=d)
    {
        r=min(r1,r2);
        return Pi*r*r;
    }
    else {
        double a1=(r1*r1+d*d-r2*r2)/(2*r1*d);
        double a2=(r2*r2+d*d-r1*r1)/(2*r2*d);
        a1=2*acos(a1);
        a2=2*acos(a2);
        return (r1*r1*(a1-sin(a1))+r2*r2*(a2-sin(a2)))*0.5;
    }

}
using namespace std;
int main()
{
    int T;
    cin>>T;
    int kase=0;
    while(T--)
    {
        double r1, r2;
        scanf("%lf%lf", &r1, &r2);
        double x1, y1, x2, y2;
        scanf("%lf%lf%lf%lf", &x1,&y1,&x2,&y2);
        Point a(x1,y1), b(x2,y2);
        circle a1(a,r1), a2(a,r2), b1(b,r1), b2(b,r2);
        printf("Case #%d: ",++kase);
        if(x1==x2&&y1==y2)
        {
            printf("%.6lf\n",Pi*(r2*r2-r1*r1)*1.0);
        }
        else
        {
            double t1, t2, t3;
            t1=area(a1,b1);
            t2=area(a2,b2);
            t3=area(a1,b2);
            printf("%.6lf\n",(t1-2*t3+t2)*1.0);
        }
    }
    return 0;
}
K:贪心

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string.h>
#include<vector>
#include<list>
#include<algorithm>
using namespace std;
const int maxn = 1e6 + 5;
vector<int> res;
int cnt[maxn];
int main()
{
    int T;
    cin >> T;
    int kase  =0;
    while(T--)
    {
        res.clear();
        memset(cnt,0,sizeof(cnt));
        int n;
        cin >> n;
        for(int i = 0; i < n; ++i)
        {
            int x;
            scanf("%d", &x);
            res.push_back(x);
        }
        int k  =0;
        for(int i = n; i >= 1; --i)
        {
            if(cnt[res.back()])
            {
                i+=1;
                res.pop_back();
                continue;
            }
            cnt[i] = 1;
            if((int)res.size() != 0 && res.back() == i)
            {
                res.pop_back();
            }
            else if((int)res.size() != 0 && res.back() != i)
            {
                ++k;
            }
        }
        printf("Case #%d: %d\n", ++kase, k);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: