【问题描述】

作为出题人的小Z相信大家对上图这样的圆盘时钟都不会陌生——在理想圆盘时钟上,秒针每一分钟转一圈,分针每一小时转一圈,时针每12小时转一圈,它们均是匀速转动的,在0点时三条针均指向表盘上的12。

考虑圆盘时钟与电子时钟之间的转换,显然,对于任意一个形如 hh:mm:ss的电子时钟式的时间(其中0 <=hh<=11,0<=mm,ss<=59),我们均可以很容易地确定时针分针秒针在理想的圆盘时钟上的位置,并计算出三条针两两之间的夹角(要求均不大于180°)。

小Z以前在Codeforces上看到一种构造题目的方法——把题目反转,于是他想到这么一个问题:如果给定三条针两两之间的夹角,那么是否可以确定当前的时刻,或者判断出有多个时刻符合条件,或者判断出不存在符合条件的时刻?

但是小Z实在太菜了,于是这个问题就被交给你来解决了。

【输入格式】

第一行为一个正整数T,表示数据组数。

接下来T组数据,每组数据一行三个用空格隔开的,形如a/b的最简分数(如果是整数,则b=1),分别表示时针与分针、时针与秒针、分针与秒针之间的夹角的度数。

【输出格式】

每组数据第一行输出一个非负整数n,表示符合条件的时刻个数,接下来n行,按照hh:mm:ss的格式(其中0<=hh<=11,0<=mm,ss<=59)从早到晚输出所有符合条件的时刻。

【样例输入】
5
0/1 0/1 0/1
90/1 90/1 0/1
60/1 60/1 60/1
55/2 5/2 30/1
45/1 135/1 180/1
【样例输出】
1
00:00:00
2
03:00:00
09:00:00
0
2
00:05:00
11:55:00
2
04:30:00
07:30:00
【数据规模与约定】

对于30%的数据,保证答案如果存在,那么mm=ss=0。

对于60%的数据,保证答案如果存在,那么ss=0。

对于100%的数据,1<=T<=500,分数a/b是既约分数,且满足0<=a<=43200,1<=b<=43200,且0<=a/b<=180。

题目分析

我们先分析一下题意:知道夹角求的是时间,我们可以枚举时间然后打表,此举不保证你会爆炸,但保证你会写的很不爽。我们分析一下假设是i时j分k秒,就得到如下关系:

时分 :30(i+j/60+k/3600)-6(j+k/60)=30i-5.5j-11/120k=(x||180-x)
时秒:30(i+j/60+k/3600)-6k=30i-0.5j-719/120k=(y||180-y)
分秒:6(j+k/60)-6k=6j-59/60k=(z||180-z)

这里有点坑啊,一个角度可能是两种情况,组合一下就有8种情况了。我们输入的时候用string分开各个比值,解一下三元一次方程组即可,解线性方程组用高斯消元就可以了。

代码实现


原来我写不出的,在这里感谢我校的大佬陈敬辉,我研究了他的代码,我想问他一句:四百多行的代码,你这是抄谁的?这题一般的省一是绝对不会的。

#include<cstdio>
#include<algorithm>
using namespace std;class fenshu{
    private:int fuhao,fenmu,fenzi;
    public:void clean(void){fenzi=1,fenmu=1,fenzi=0;}
        void prepare(int s,int d,int n){if(!d) return;
            fuhao=s,fenzi=n,fenmu=d;
            int gcd=__gcd(fenzi,fenmu);
            fenzi/=gcd,fenmu/=gcd;
        }int FUHAO(){return fuhao;}
        int FENZI(){return fenzi;}
        int FENMU(){return fenmu;}
        void Abs(void){fuhao=1;}
        fenshu operator+(fenshu X){fenshu ans;
            ans.clean(),ans.fenmu=fenmu*X.fenmu,ans.fenzi=0;
            fuhao?ans.fenzi+=fenzi*X.fenmu:ans.fenzi-=fenzi*X.fenmu;
            X.fuhao?ans.fenzi+=X.fenzi*fenmu:ans.fenzi-=X.fenzi*fenmu;
            ans.fuhao=ans.fenzi>=0?1:0;
            if(!ans.fuhao) ans.fenzi=-ans.fenzi;
            int gcd=__gcd(ans.fenzi,ans.fenmu);
            ans.fenzi/=gcd,ans.fenmu/=gcd;
            return ans;
        }fenshu operator-(fenshu X){fenshu ans;
            ans.clean(),ans.fenmu=fenmu*X.fenmu,ans.fenzi=0;
            fuhao?ans.fenzi+=fenzi*X.fenmu:ans.fenzi-=fenzi*X.fenmu;
            X.fuhao?ans.fenzi-=X.fenzi*fenmu:ans.fenzi+=X.fenzi*fenmu;
            ans.fuhao=ans.fenzi>=0?1:0;
            if(!ans.fuhao) ans.fenzi=-ans.fenzi;
            int gcd=__gcd(ans.fenzi,ans.fenmu);
            ans.fenzi/=gcd,ans.fenmu/=gcd;
            return ans;
        }fenshu operator*(fenshu X){fenshu ans;
            ans.clean(),ans.fenmu=fenmu*X.fenmu,ans.fenzi=fenzi*X.fenzi;
            ans.fuhao=fuhao==X.fuhao?1:0;
            if(ans.fenmu<0) ans.fenmu=-ans.fenmu;
            if(ans.fenzi<0) ans.fenzi=-ans.fenzi;
            int gcd=__gcd(ans.fenzi,ans.fenmu);
            ans.fenzi/=gcd,ans.fenmu/=gcd;
            return ans;
        }fenshu operator/(fenshu X){fenshu ans;
            ans.clean(),ans.fenmu=fenmu*X.fenzi,ans.fenzi=fenzi*X.fenmu;
            ans.fuhao=fuhao==X.fuhao?1:0;
            if(ans.fenmu<0)    ans.fenmu=-ans.fenmu;
            if(ans.fenzi<0)    ans.fenzi=-ans.fenzi;
            int gcd=__gcd(ans.fenzi,ans.fenmu);
            ans.fenzi/=gcd,ans.fenmu/=gcd;
            return ans;
       }bool operator==(fenshu X){return fenzi==X.fenzi&&fenmu==X.fenmu;}
        bool operator>=(fenshu X){fenshu ans;
            ans.clean(),ans.fenmu=fenmu*X.fenmu,ans.fenzi=0;
            fuhao?ans.fenzi+=fenzi*X.fenmu:ans.fenzi-=fenzi*X.fenmu;
            X.fuhao?ans.fenzi-=X.fenzi*fenmu:ans.fenzi+=X.fenzi*fenmu;
            return ans.fenzi>=0;
        }bool operator <= (fenshu X){fenshu ans;
            ans.clean(),ans.fenmu=fenmu*X.fenmu,ans.fenzi=0;
            fuhao?ans.fenzi+=fenzi*X.fenmu:ans.fenzi-=fenzi*X.fenmu;
            X.fuhao?ans.fenzi-=X.fenzi*fenmu:ans.fenzi+=X.fenzi*fenmu;
            return ans.fenzi<=0;
        }bool operator>(fenshu X){fenshu ans;
            ans.clean(),ans.fenmu=fenmu*X.fenmu,ans.fenzi=0;
            fuhao?ans.fenzi+=fenzi*X.fenmu:ans.fenzi-=fenzi*X.fenmu;
            X.fuhao?ans.fenzi-=X.fenzi*fenmu:ans.fenzi+=X.fenzi*fenmu;
            return ans.fenzi>0;
        }bool operator<(fenshu X){fenshu ans;
            ans.clean(),ans.fenmu=fenmu*X.fenmu,ans.fenzi=0;
            fuhao?ans.fenzi+=fenzi*X.fenmu:ans.fenzi-=fenzi*X.fenmu;
            X.fuhao?ans.fenzi-=X.fenzi*fenmu:ans.fenzi+=X.fenzi*fenmu;
            return ans.fenzi<0;
        }void read(){char s[51];scanf("%s",s);int t=0;
            s[0]=='-'?fuhao=0,t=1:fuhao=1,t=0;
            fenmu=fenzi=0;
            while(s[t]^'/')    fenzi=fenzi*10+s[t]-'0',++t;
            ++t;while(s[t]^'\0') fenmu=fenmu*10+s[t]-'0',++t;
            if(!fenmu){clean();return;}
            int gcd=__gcd(fenzi,fenmu);
            fenzi/=gcd,fenmu/=gcd;}
}hour_minute,hour_second,minute_second,hour_0,minute_0,second_0,l59,step_s,zero,one,full,full6,full12,full30,full60,full3600,temp;
class time{public:int hour,minute,second;
    bool operator!=(time x){return hour^x.hour||minute^x.minute||second!=x.second;}
    friend bool operator<(time x,time y){
        if(x.hour^y.hour) return x.hour<y.hour;
        if(x.minute^y.minute) return x.minute<y.minute;
        return x.second<y.second;}
}anss[43200],_anss[43200];
int _ans,T,ans;
fenshu change(fenshu x){
    while(x<zero)    x=x+full;
    while(x>full)    x=x-full;
    return x;
}void check(){fenshu minute,hour;
    hour_0=change(second_0+hour_second);
    if(hour_0==change(minute_0+hour_minute)||hour_0==change(minute_0-hour_minute)){
        minute=minute_0;
        while(minute>=full6)    minute=minute-full6;
        minute=minute/full6*full;
        if(second_0==minute){
            minute=minute_0,minute=minute/full6*full,hour=hour_0;
            while(hour>=full30)    hour=hour-full30;
            hour=hour*full12*full60;
            if(hour==minute){anss[ans].hour=0;
                for(temp=hour_0;temp>=full30;temp=temp-full30,++anss[ans].hour);
                anss[ans].minute=0;
                for(temp=minute_0;temp>=full6;temp=temp-full6,++anss[ans].minute);
                anss[ans].second=0;
                for(temp=second_0;temp>=full6;temp=temp-full6,++anss[ans].second);
                ++ans;
  }}}hour_0=change(second_0-hour_second);
    if(hour_0==change(minute_0+hour_minute)||hour_0==change(minute_0-hour_minute)){
        minute=minute_0;
        while(minute>=full6) minute=minute-full6;
        minute=minute/full6*full;
        if(second_0==minute){
            minute=minute_0,minute=minute/full6*full,hour=hour_0;
            while(hour>=full30)    hour=hour-full30;
            hour=hour*full12*full60;
            if(hour==minute){
                anss[ans].hour=0;
                for(temp=hour_0;temp>=full30;temp=temp-full30,++anss[ans].hour);
                anss[ans].minute=0;
                for(temp=minute_0;temp>=full6;temp=temp-full6,++anss[ans].minute);
                anss[ans].second=0;
                for(temp=second_0;temp>=full6;temp=temp-full6,++anss[ans].second);
                ++ans;
}}}}signed main(){
    hour_minute.clean(),hour_second.clean(),minute_second.clean(),hour_0.clean(),minute_0.clean();
    second_0.clean(),l59.clean(),l59.prepare(1,1,354),step_s.clean(),step_s.prepare(1,1,6),zero.clean();
    one.clean(),full.clean(),full60.clean(),full3600.clean(),temp.clean(),full30.clean(),full6.clean();
    full12.clean(),zero.prepare(1,1,0),one.prepare(1,1,1),full.prepare(1,1,360),full60.prepare(1,1,60);
    full3600.prepare(1,1,3600),full30.prepare(1,1,30),full6.prepare(1,1,6),full12.prepare(1,1,12);
    scanf("%d",&T);
    fenshu pd;pd.prepare(1,20,39);
    while(T--){
        hour_minute.read(),hour_second.read(),minute_second.read(),ans=0;
        for(second_0.prepare(1,1,0);second_0<=l59;second_0=second_0+step_s)
            minute_0=change(second_0+minute_second),check(),minute_0=change(second_0-minute_second),check();
        sort(anss,anss+ans);
        if(ans){_anss[0].hour=anss[0].hour;
            _anss[0].minute=anss[0].minute;
            _anss[0].second=anss[0].second;_ans=1;
            for(int i=1;i<ans;++i)
                if(anss[i]!=anss[i-1]){
                    _anss[_ans].hour=anss[i].hour;
                    _anss[_ans].minute=anss[i].minute;
                    _anss[_ans++].second=anss[i].second;
                }
        }printf("%d\n",_ans);
        for(int i=0;i<_ans;++i)
            printf("%02d:%02d:%02d\n",_anss[i].hour,_anss[i].minute,_anss[i].second);
    }
}

代码说明

这篇代码挺长,这道题非常不好写。我的思路可行,正解是直接按照暴力来做,枚举可能出现的点,然后去重。我用了类模板在这里,这个东西可以在我的工程C++中看到,不过我没用自己的定义类,而是类struct的模板。

首先读入数据,这个和快读同理,注意的是\0代表的是空字符,就是空格,换行和制表符。然后我们对可能出现的时间进行变换,怎么做呢?把时间枚举出来,然后变成分数暴力判断,用operator重载。枚举的时候用了倍增的思想。最后输出的时候要排序去重,其实这里本来是重载了unique的,现在它没有了。

今天发生了一些变故,我深深的感到了人心不古。

posted on 2019-03-21 23:49  aserrrre  阅读(341)  评论(0编辑  收藏  举报