編程之美 格格取數問題

來源:互聯網
上載者:User

參考了:http://blog.csdn.net/liuguidongliuguidong/article/details/23474573

現在還無法確定這個方法是否正確,反正是AC了,參考處的首頁君的代碼自己去看看吧,我寫出我的兩個版本的代碼,然後引出問題所在。

1.WA代碼:

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
struct node{
    int v;
    int x,y;
}nums[10001];
bool cmp(node a, node b){
    return a.v < b.v;
}
int main(){
    int T,m,n;
    int minSum = 0;
    int cx[101],cy[101];
    int cover = 0,index;
    scanf("%d",&T);
    for(int t = 1;t <= T;t++){
        scanf("%d %d",&m,&n);
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                scanf("%d",&nums[i * n + j].v);
                nums[i * n + j].x = i;
                nums[i * n + j].y = j;
                cy[j] = 0;
            }
            cx[i] = 0;
        }
         minSum = 0;
         cover = m + n;
         index = 0;
         sort(nums,nums + (m * n),cmp);
         while(cover > 0){
             cover -= (cx[nums[index].x] == 0) ? 1 : 0;
             cover -= (cy[nums[index].y] == 0) ? 1 : 0;
             cx[nums[index].x]++;
             cy[nums[index++].y]++;
         }
         for(int i = 0;i < index;i++){
             if(cx[nums[i].x] > 1 && cy[nums[i].y] > 1){
                 cy[nums[i].y]--;
                 cx[nums[i].x]--;
             }else{
                 minSum += nums[i].v;
             }
         }
         printf("Case %d: %d\n",t,minSum);
    }
    return 0;
}

2.AC代碼:

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
struct node{
    int v;
    int x,y;
}nums[10001];
bool cmp(node a, node b){
    return a.v < b.v;
}
bool cmp1(node a,node b){
    return a.v > b.v;
}
int main(){
    int T,m,n;
    int minSum = 0;
    int cx[101],cy[101];
    int cover = 0,index;
    scanf("%d",&T);
    for(int t = 1;t <= T;t++){
        scanf("%d %d",&m,&n);
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                scanf("%d",&nums[i * n + j].v);
                nums[i * n + j].x = i;
                nums[i * n + j].y = j;
                cy[j] = 0;
            }
            cx[i] = 0;
        }
        sort(nums,nums + (m * n),cmp);
        minSum = 0;
        cover = m + n;
        index = 0;
        while(cover > 0){
            if(cx[nums[index].x] == 0)cover--;
            if(cy[nums[index].y] == 0)cover--;
            cx[nums[index].x]++;
            cy[nums[index++].y]++;
        }
        sort(nums,nums + index,cmp1);
        for(int i = 0;i < index;i++){
            if(cx[nums[i].x] > 1 && cy[nums[i].y] > 1){
                cy[nums[i].y]--;
                cx[nums[i].x]--;
            }else{
                minSum += nums[i].v;
            }
        }
        printf("Case %d: %d\n",t,minSum);
    }
    return 0;
}

    不同點僅在藍色部分,下面分析下為什麼藍色部分會導致兩種結果。

    個人猜測是標程有問題。解題思路大概是:

        a.先對方格中的所有數從小大待排序;

        b.然後對方格從小到大覆蓋,直至所有的行和列都覆蓋即停;

        c.對被選來覆蓋的那些數進行再次排序,但是是從大到小排序(關鍵);

        d.然後對排序後的數從大到小掃,去掉多餘的,即其所在行和列都已經有其他的數。

        e.去掉的同時也計算該留下的那些數的總和即可。

    我的第一份WA的代碼看上去跟第二份沒什麼區別,第一份沒有對選中的數再次排序,第二份對選中的數排序了。這操作之後對數組唯一的區別在於對相同值的數的排列,比如:設有三個數a{v=3,x=0,y=0}、b{v=3,x=1,y=1}、c{v=3,x=1,y=2}:

        a.在我的WA代碼裡:只排了一次序,沒搞錯的話順序應該是:a-b-c,然後就開始從後往前掃,一直刪除,這樣最先遭殃的是c,然後b,最後才是a;

        b.而在我的AC代碼裡:除了最先的升序排序外,後面還進行了對已選的數在進行一次降序排序,雖然那三個數最後的結果還是a-b-c的順序,但是我是從前往後掃,結果就              是最先遭殃的應該是a,然後是b,最後才是c.

    在這種情況下,有可能的情況就是a,b,c對其它的同行或者同列的數有一定影響,而因為先後騷的順序不一樣而導致最後結果可能有差異,不過這種到底是哪個正確本人還搞不清楚,暫且就按標程的走,但是對於這兩份代碼的正確性我也沒法保證,因為腦子不行+懶,以後有時間再去證證,可能只是很簡單的證明吧。






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.