14周限时大模拟
给定新番时间表,猫咪的最小睡眠时长和最大清醒时长,判断是否存在满足要求的时间管理办法,若是存在则给出一种。
输入新番时间表后对时间进行排序,如果相邻两个时间段间隔大于最小睡眠时长,则猫咪睡觉,清醒初始时间重置为第二时间段起始时间,相反,猫咪清醒,清醒初始时间不变。如果清醒时间大于最大清醒时长,则不存在满足要求的时间管理办法,反之如果一直小于最大清醒时长,证明存在,输出睡觉的时间段即可。
这道题有这几个难点:一:可能出现跨夜的情况,首先对于跨夜时间段而言,我们需要将结束时间加24小时以表示跨夜。其次,跨夜就说明解决问题时不能将范围局限在24小时内,为保证连续性,我们至少需要看48个小时内的情况,这就需要我们在输入时间段后,再对每一个时间段的每一个时间做加24小时的处理以模拟第二天的时间表。二:时间表所表示的时间范围为闭区间,所以在计算时长时不能只进行简单的加减法,清醒时长为计算中两个时刻间隔加1分钟,睡眠时长为计算中两个时刻间隔减1分钟.。三,由于时间表表示范围为闭区间,则起始睡眠时间为计算中起始时刻加1分钟,睡眠结束时间为计算中结束时间减1分钟,这就又涉及到跨小时甚至跨天的情况,要对可能出现的跨越情况进行处理,才能得到符合要求且答案正确的时间表。
#include<iostream>
#include<vector>
#include<algorithm>
#include<stdio.h>
#include<set>
using namespace std;
struct Time{
int time1,time2;
bool operator<(const Time &b) const {
if (time1!=b.time1)return time1<b.time1;
else return time2<b.time2;}
Time operator=(const Time &b) {
time1=b.time1;
time2=b.time2;}
};
vector<Time> t;
set<Time> ans;
int s_time(Time t){
int time=0;
time=t.time2-t.time1;
return time;
}
bool awake(int ans,int B){
if(ans+1<=B*60) return true;
else return false;
}
bool sleep(int ans,int A){
if(ans-1>=A*60) return true;
else return false;
}
int main(){
int A,B,N;
int h1,m1,h2,m2;
while(scanf("%d %d %d",&A,&B,&N)!=EOF){
t.clear();
ans.clear();
Time t1;
for(int i=0;i<N;i++){
scanf("%d:%d-%d:%d",&h1,&m1,&h2,&m2);
t1.time1=h1*60+m1;
t1.time2=h2*60+m2;
if(t1.time2<t1.time1) t1.time2=t1.time2+1440;
t.push_back(t1);
t1.time1=t1.time1+1440;
t1.time2=t1.time2+1440;
t.push_back(t1);}
sort(t.begin(),t.begin()+t.size());
Time ts,ta;
int ans1,ans2;
int flag1=0,flag=0;
for(int i=0;i<t.size();i++){
if(flag1==0){
flag1=1;
ta.time1=t[i].time1;}
ta.time2=t[i].time2;
ans1=s_time(ta);
if(!awake(ans1,B)){cout<<"No"<<endl;flag=1;break;}
if(i<t.size()-1){
ts.time1=t[i].time2;
ts.time2=t[i+1].time1;
ans2=s_time(ts);
if(sleep(ans2,A)){
flag1=0;
ts.time1=(ts.time1+1)%1440;
ts.time2=(ts.time2-1+1440)%1440;
ans.insert(ts);}
}}
if(flag!=1){
cout<<"Yes"<<endl;
cout<<ans.size()<<endl;
set<Time>::iterator p;
for(p=ans.begin();p!=ans.end();p++){
h1=(*p).time1/60;
m1=(*p).time1%60;
h2=(*p).time2/60;
m2=(*p).time2%60;
printf("%02d:%02d-%02d:%02d\n",h1,m1,h2,m2);
}
}}
}
TT数鸭子
给定数字个数和数字种类数,判断数字中有多少数字其种类数小于给定的数字种类数。
每一次取一位数字,如果统计过则忽略,反之则种类数加一,为节约时间,若种类数已超过题目要求,直接舍弃该数字,不再统计。若某一数字种类数符合要求,则结果加一,直至统计完所有数字输出结果。
#include<iostream>
#include<string>
#include<string.h>
#include<stdio.h>
using namespace std;
long long int num;
int f[15];
int main(){
int n,k;
cin>>n>>k;
int sum=0;
for(int i=0;i<n;i++){
memset(f,0,sizeof(f));
scanf("%lld",&num);
int j=0;
int l=0;
int p=0;
while(num>0&&p<k){
if(f[num%10]==0){f[num%10]=1;p++;}
num=num/10;}
if(p<k){sum++;}
}
cout<<sum<<endl;
}
抵御宇宙射线
给定宇宙射线发射点的个数和每个点的坐标,输出保护罩的中心坐标(为某一发射点)和保护罩半径的平方(要求保护罩面积最小)。
若要覆盖所有的发射点,保护罩的半径就是中心坐标与距中心坐标最远点的距离,若要面积最小,则要找到满足最远间距最小的中心坐标。由于点数较少,我们可以依次遍历找以每一个点为中心坐标时的最远间距,然后比较得到最小的最远间距与中心坐标,即实现实验要求
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
struct point{
long long int x,y;
bool operator<(const point&p){
if(x!=p.x){return x<p.x;}
else return y<p.y;
}
};
point p[1005];
long long num_pos(point a,point b){
long long ans=1;
ans=(a.x-b.x)*(a.x-b.x)*ans+(a.y-b.y)*(a.y-b.y)*ans;
return ans;
}
long long m[1005];
int main(){
int N;
cin>>N;
for(int i=0;i<N;i++){cin>>p[i].x>>p[i].y;}
sort(p,p+N);
for(int i=0;i<N;i++){
for(int j=i;j<N;j++){
m[i]=max(m[i],num_pos(p[i],p[j]));
m[j]=max(m[j],num_pos(p[i],p[j]));
}
}
long long int mi=9999999999999;
int x1,y1;
for(int i=0;i<N;i++){
if(mi>m[i]){mi=m[i];x1=p[i].x;y1=p[i].y;}
}
cout<<x1<<".00 "<<y1<<".00"<<endl;
cout<<mi<<".00"<<endl;
}
宇宙狗的危机
给定一组数,判断这些数能否拼成一棵二叉搜索树且满足任意连个节点的最大公约数都超过一。
如果一开始就从所有数据来考虑,情况过于复杂,显然是不可取的。仔细分析,如果树存在,那么对于任何一个节点,其左右孩子(如果存在)必不与该节点互质,其左右子树(如果存在)一定也是满足条件的二叉搜索树。基于这个思想,我们可以不断构建较小的二叉搜索子树,进而判断是否最终可以合并为由整组数据构成的二叉搜索树。
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,flag;
int a[705],l[705][705],r[705][705],g[705][705];
int gcd(int a,int b) {return b==0?a:gcd(b,a%b);}
int main(){
int T;
cin>>T;
for(int t=0;t<T;t++){
cin>>n;
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
memset(g,0,sizeof(g));
flag=0;
for(int i=0;i<n;i++){
cin>>a[i];
l[i][i]=1;
r[i][i]=1;}
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(gcd(a[i],a[j])>1){g[i][j]=1;g[j][i]=1;}}}
for(int len=0;len<n;len++)
for(int p=0;p+len<n;p++){
int q=p+len;
for(int k=p;k<=q;k++){
if(l[p][k]&&r[k][q]){
if(p==0&&q==n-1) flag=1;
if(g[p-1][k]) r[p-1][q]=1;
if(g[k][q+1]) l[p][q+1]=1;
}}}
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}