A. Free Cash
赛中就A了这一题,唉~~继续努力
这题很简单,最主要的是要看懂题目,我看题目的速度太慢,理解慢,oh~~要加强阅读理解能力
题意:Valera要服务客人,每一个客人到达餐店的时间不Valera同,但是顾客来的时候Valera没有活动现金客人就会走,为了保证能留下更多客人,Valera至少要带多少活动现金
其实简单的理解就是求每个客人到达的时间其相同的个数然后取最大值
代码:
#include <iostream>//A
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
int h;
int m;
int a[100005];
int main()
{
int n,i,s=0,max=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d %d",&h,&m);
s=h*60+m;
a[s]++;//每一个时间点它的总数
if(a[s]>max)//取最大值
max=a[s];
}
cout<<max<<endl;
return 0;
}
B. Young Table
这题其实题目看清楚了也不太难,我当时虽然知道交换步骤数不要求最小,但是要小于数组的个数S,汗颜!!!当时脑子晕了,不管怎样,就算数组完全无序,要交换成有序的,其步骤也不会超过S,想到这个,题目就可以做了
其实我花了很久的时间才弄出这题,刚开始我以为给出的所有数不同,直接用一个数组把它的坐标记录下来就行了,后来发现可以有相同的,那么我就必须改了~~
代码:
#include <iostream>//B
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
int num[55];
struct node
{
int x,y;
int data;
} a[100005],b[100005];//改后a b 数组都是结构体
int s[100005];
bool f(node a,node b)
{
return a.data<b.data;
}
int main()
{
int i,j,n,data,k=1,k1=0;
scanf("%d",&n);
for(i=1; i<=n; i++)
scanf("%d",&num[i]);
for(i=1; i<=n; i++)
{
for(j=1; j<=num[i]; j++)
{
scanf("%d",&data);
a[k].x=i; //放到一维数组里并记录坐标
a[k].y=j;
a[k].data=data;
b[k].x=i;
b[k].y=j;
b[k].data=data;
k++;
k1++;
}
}
int g=0,g2=0;
sort(b+1,b+k1+1,f);
for(i=1; i<=k1; i++)
{
if(a[i].data!=b[i].data)//把原数组和排序后的标准数组b做比较
{
s[g++]=a[i].x;
s[g++]=a[i].y;
int h;
for(h=1; h<=k1; h++)
{
if(a[h].data==b[i].data)//在原数组中找到要交换的那个数
{
break;
}
}
s[g++]=a[h].x;//我错在这里了~我之前是s[g++]=b[i].x ;s[g++]=b[i].y;后来知道快速排序是不稳定的,不能直接用b[i]里的坐标,如果有相同
s[g++]=a[h].y;//的数,那么b[i].x就不一定==a[h].x,b[i].y就不一定==a[h].y
swap(a[i].data,a[h].data);
g2++;
}
}
printf("%d\n",g2);
int f=0;
for(i=0; i<g; i++)
{
f++;
if(f==4)
{
printf("%d\n",s[i]);
f=0;
}
else
printf("%d ",s[i]);
}
return 0;
}
C. Primes on Interval
题意:给你一个区间【a,b】,让你找到最小的 L(1<=L<=b-a+1),使得对于从任意的一个数 x (a<=x<=b-L+1)开始,连续的L个数即x,x + 1,..., x + L- 1 中至少有K个素数。
如果按平常方法用三个for循环来求极有可能会超时,我弄了好久,用这种方法还是超时。。。。
这题要保证不超时,就必须对素数进行线性筛选,还有重要一步:很重要!很重要!因为每一次都要求一个区间的素数个数,所以索性先求每一个数之前有几个素数,优化一下。。。
由于只用循环来做会超时,因此现在只能采用二分法了,如果上面讲的重要的一步不用,二分也会超时,我试过了。。泪呀!
代码:
#include <iostream>//C
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
int prim[1000005]= {0};
int pnum[1000005]= {0};
int a,b,k;
int main()
{
int i,j;
prim[1]=1;
for(i=2; i<=1000005; i++)//帅选素数
{
for(j=2*i; j<=1000005; j+=i)
prim[j]=1;
}
scanf("%d%d%d",&a,&b,&k);
for(i=2; i<=b; i++) //先算出每一个数之前有几个素数包括它本身
{
pnum[i]=pnum[i-1];
if(!prim[i])
pnum[i]++;
}
if(pnum[b]-pnum[a-1]<k)
{
printf("-1\n");
}
else
{
int low=1,high=b-a+1,lmid,x;
while(low<high)
{
int flag=0;
lmid=(low+high)/2;
for(x=a;x<=b-lmid+1;x++)
{
if(pnum[x+lmid-1]-pnum[x-1]<k)
flag=1;
}
if(flag==0)
high=lmid;
else
low=lmid+1;
}
printf("%d\n",low);
/* int l,x;
for( l=1; l<=b-a+1; l++)//导致超时的代码
{
int flag=0;
for(x=a; x<=b-l+1; x++)
{
int sum=pnum[x+l-1]-pnum[x-1];
if(sum<k)
{
flag=1;
break;
}
}
if(x==b-l+2 && flag==0)
{
printf("%d\n",l);
break;
}
}*/
}
return 0;
}
D.T-decomposition
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int M=100005;
int n;
int a[M];
int b[M];
vector<int>V[M];
int main()
{
int i,j;
scanf("%d",&n);
for(i=1; i<n; i++)
{
scanf("%d%d",&a[i],&b[i]);
V[a[i]].push_back(i);
V[b[i]].push_back(i);
}
printf("%d\n",n-1);
for(i=1; i<n; i++)
printf("2 %d %d\n",a[i],b[i]);//有n-1条边
for(i=1; i<=n; i++)
{
for(j=1; j<V[i].size(); j++)
printf("%d %d\n",V[i][j-1],V[i][j]);
}
return 0;
}
E题太神,先放先。。。