2018 ICPC Greater New York Regional Contest E. What time is it anyway?(搜索,或匈牙利算法)

What time is it anyway?

The \text{Frobozz Magic Clock Company}Frobozz Magic Clock Companymakes 12-hour analog clocks that are always circular and have an hour hand and a minute hand as shown below:

The shop has NN clocks all possibly showing different times. The clocks show different times so the customers can see what the otherwise identical clocks would look like at different times. Each clock has a label card that is supposed to be affixed to the back of the clock indicating the \text{time difference}time difference from the correct time.

Before beginning his trek across the \text{Eastlands, Lord Dimwit Flathead}Eastlands, Lord Dimwit Flatheadworked at the \text{Frobozz Magic Clock Company}Frobozz Magic Clock Company for less than a single day in 741 GUE when he was summarily fired for removing all the labels from backs of the clocks "in order to clean them", or so he says. The labels were strewn about the floor as a result of Dimwit's "cleaning" process. In order to replace each label on its respective clock, it would be a great help to know the current time. This is where you come in. You will write a program to print out the correct time given the time shown on each clock and the time differences shown on the labels. Note the labels are mixed up and you do not know which clock they belong to.

Input

The first line of input contains a single decimal integer PP, (1 \le P \le 10000)(1≤P≤10000), which is the number of data sets that follow. Each data set should be processed identically and independently.

Each data set consists of multiple lines of input. The first line contains the data set number, KK, followed by the number of clocks, NN, (1 \le N \le 10)(1≤N≤10). The next NN lines each specify the time on a clock in the form \text{H:MM}H:MM, (1 \le H \le 12, 0 \le MM \le 59)(1≤H≤12,0≤MM≤59). The next NN lines each specify an offset from the current time in the form [+/-]\text{h:mm}h:mm, (0 \le h \le 10000, 0 \le mm \le 59)(0≤h≤10000,0≤mm≤59). MMMM and mmmm are zero padded to 2 digits on the left, so 9 would be 09 and 11 would be 11.

Output

For each data set there is a single line of output.

The single line of output consists of the data set number, KK, followed by a single space followed by the current time for the given data set. If no time can be found to match input data, then the output is the data set number, KK, followed by a single space followed by the word "none". If more than one time is found that satisfies the input data, then the output is the data set number, KK, followed by a single space followed by the number of different times that match the input data.

样例输入

3
1 2
1:05
8:35
-3:15
+1:15
2 2
3:00
9:00
+3:00
-3:00
3 2
3:00
9:00
+6:00
-6:00

样例输出

1 11:50
2 2
3 none

题意:(只说关键部分), 给你一个整数 n, 接下来有 n 个时间 (时间都是12小时制的,为表上的时间), 然后有 n 个可用来加减的时间(用正负表示), '+' 表示实际时间  比  表上的时间快, '-' 表示实际时间  比  表上时间慢,最后要用这 n 个时间与 加减的时间任意匹配, 问 是否可能   全部匹配后,时间相同。如果只有 1 种相同时间,输出这个时间,有多种 则输出总数,没有输出 none. (还有坑点就是输入的时候 +  和 - 用char 进行输入,只依靠正负数判断 会 出现 -0 与 +0的情况(我就是这样被坑了4个小时QAQ),合法时间要去重)

思路:1:暴力搜索 一 一匹配  。 2:用所有可能出现的时间,对于所用的时间下标建图,然后匈牙利找最大匹配数,若最大匹配数 == n, 那么这个时间就是合法的。

代码1,暴力搜索:

#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define INT(t) int t; scanf("%d",&t)
#define LLI(t) LL t; scanf("%I64d",&t)

using namespace std;

int cal(int h, int m, int hh, int mm) {
    hh %= 12;
    h += hh, m += mm;
    if(m >= 60)
        m -= 60, h++;
    else if(m < 0)
        h--, m += 60;

    if(-12 < h && h <= 0)
        h += 12;
    else if(h > 24)
        h -= 24;
    else if(h > 12)
        h -= 12;
    return h * 100 + m;
}

int H[20], M[20];
int HH[20], MM[20];
int vis[20], n, k;
vector<int> ans;

void dfs(int x, int coun, int be) {
    if(coun == n) {
        ans.push_back(x);
        return ;
    }
    if(be > n) return ;
    for(int j = 1; j <= n; ++ j) {
        if(vis[j])
            continue;
        if(cal(H[be], M[be], HH[j], MM[j]) != x)
            continue;
        vis[j] = 1;
        dfs(x, coun + 1, be + 1);
        vis[j] = 0;
    }

}

int main() {
    int p;
    scanf("%d", &p);
    while(p --) {
        scanf("%d%d", &k, &n);
        for(int i = 1; i <= n; ++ i)
            scanf("%d:%d", &H[i], &M[i]);
        char ch;
        for(int i = 1; i <= n; ++ i) {
            scanf(" %c%d:%d", &ch, &HH[i], &MM[i]);
            if(ch == '+') {
                HH[i] = -HH[i];
                MM[i] = -MM[i];
            }
        }
        ans.clear();
        for(int j = 1; j <= n; ++ j) {
            vis[j] = 1;
            dfs(cal(H[1], M[1], HH[j], MM[j]), 1, 2);
            vis[j] = 0;
        }
        printf("%d ", k);
        sort(ans.begin(),ans.end());
        int en = unique(ans.begin(),ans.end()) - ans.begin();
        if(!en)
            printf("none\n");
        else if(en == 1) {
            printf("%d:", ans[0] / 100);
            if(ans[0] % 100 < 10)
                printf("0");
            printf("%d\n", ans[0] % 100);
        } else
            printf("%d\n", en);
    }
    return 0;
}

 

代码  匈牙利:

#include<bits/stdc++.h>
using namespace std;
#define MP make_pair
#define clr(a,b) memset((a),(b),sizeof(a))
#define fuck(x) std::cout << "[" << #x << "]:" << x << endl

int cal(int h, int m, int hh, int mm) {
    hh %= 12;
    h += hh, m += mm;
    if(m >= 60)
        m -= 60, h++;
    else if(m < 0)
        h--, m += 60;

    if(-12 < h && h <= 0)
        h += 12;
    else if(h > 24)
        h -= 24;
    else if(h > 12)
        h -= 12;
    return h * 100 + m;
}

int H[20],M[20];
int HH[20],MM[20];
int k,n;
vector<pair<int,int> > v[1400];
int mp[20][20];
bool used[20];
int linker[20];

bool dfs(int u){
    int v;
    for(v = 1;v <= n;++ v){
        if(mp[u][v] && !used[v]){
            used[v] = 1;
            if(linker[v] == -1 || dfs(linker[v])){
                linker[v] = u;
                return true;
            }
        }
    }
    return false;
}

int hungary(){
    int res = 0;
    clr(linker,-1);
    for(int u = 1;u <= n;++ u){
        clr(used,0);
        if(dfs(u))
            ++ res;
    }
    return res;
}

int main()
{
    int p; scanf("%d",&p);
    while(p --){
        scanf("%d%d",&k,&n);
        for(int i = 1;i <= n;++ i){
            scanf("%d:%d",&H[i],&M[i]);
        }
        char ch;
        for(int i = 1;i <= n;++ i){
            scanf(" %c%d:%d",&ch,&HH[i],&MM[i]);
            if(ch == '+'){
                HH[i] = -HH[i];
                MM[i] = -MM[i];
            }
        }
        for(int i = 1;i < 1400;++ i) v[i].clear();
        for(int i = 1;i <= n;++ i)
            for(int j = 1;j <= n;++ j)
                v[cal(H[i],M[i],HH[j],MM[j])].push_back(MP(i,j));

        vector<int> ans;
        for(int i = 0;i < 1400;++ i){
            if(v[i].size() < n) continue;
            clr(mp,0);
            for(int j = 0;j < v[i].size();++ j){
                mp[v[i][j].first][v[i][j].second] = 1;
            }
            int t = hungary();
            if(t == n){
                ans.push_back(i);
            }
        }
        sort(ans.begin(),ans.end());
        int en = unique(ans.begin(),ans.end()) - ans.begin();
        printf("%d ",k);
        if(!en) printf("none\n");
        else if(en == 1){
            printf("%d:",ans[0] / 100);
            if(ans[0] % 100 < 10) printf("0");
            printf("%d\n",ans[0] % 100);
        }
        else printf("%d\n",en);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值