XJOI 奋斗群群赛6
A - Fraction
题意
输入一个数n,输出一对和为n且互质的数。
题解
调用了STL库中的__gcd函数,最大公约数为1即为两数互质。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=n/2;i>=1;i--){
if(__gcd(i,n-i)==1){
cout<<i<<" "<<n-i;
return 0;
}
}
}
B - Maxim Buys an Apartment
题意
输入一个数n代表房子总数,再输入一个数k代表有人住的房子数量。n个房子排成直线,如果一个空房子的左侧或右侧有人住,则该房子为好,要求求出最小和最大的好的房子的数量。
题解
水题,分类讨论即可。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,k;
cin>>n>>k;
if(n==k||k==0){
cout<<"0"<<" "<<"0";
}
else if(k<=n/3){
cout<<"1"<<" "<<2*k;
}
else cout<<"1"<<" "<<n-k;
}
C - Planning
题意
给出n个航班和其延误代价,每个航班应在第i分钟出发,否则每延误一分钟付出相应代价,因某种原因,这些航班在开始的k分钟不能起飞,要求从k+1分钟起排出一张时间表,使得代价最小。
题解
基本算法贪心,在这里想到通过维护优先队列使时间复杂度降至O(logN),WA的两次是因为爆int了。
#include<bits/stdc++.h>
using namespace std;
struct planning_s {
int x;
int num;
friend bool operator < (planning_s u,planning_s v) {
return u.x<v.x;
}
}a[300001];
int main() {
int n,k;
int ans[300001];
long long int res=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i].x);
a[i].num=i;
}
priority_queue <planning_s> q;
for(int i=1;i<=k;i++) {
q.push(a[i]);
}
for(int i=k+1; i<=k+n; i++) {
if(i<=n) {
q.push(a[i]);
}
planning_s temp=q.top();
q.pop();
res=res+(long long int)(i-temp.num)*(long long int)(temp.x);
ans[temp.num]=i;
}
cout<<res<<endl;
for(int i=1; i<=n; i++) {
printf("%d ",ans[i]);
}
return 0;
}
D - Jury Meeting
题意
输入n,有n+1个城市从0标号至n,其中0表示大都会,其余的城市每个城市都住有一个人,输入m,代表有m个航班,每个航班有四个数据:日期,出发城市,到达城市,价格,再输入k,要求求出使这n个人通过航班到达城市0,并停留k天后,再乘航班返回原城市的最小代价。
题解
预处理时对于每一架航班,使用结构体存储它的四个数据,之后按出发日期进行排序,之后正着扫一遍出发的最小价格,反向扫一遍返航的最小价格即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll inf=1e17;
const int MAXN=2000100;
struct node{
ll d;
ll f;
ll t;
ll c;
}a[MAXN];
bool cmp(node a,node b){
return a.d<b.d;
}
ll b[MAXN],ans[MAXN],ans1[MAXN];
int main(){
ll i,j;
ll n,m,k;
cin>>n>>m>>k;
for(i=1;i<=MAXN;i++){
b[i]=-1;
ans[i]=inf;
}
for(i=1;i<=m;i++){
cin>>a[i].d>>a[i].f>>a[i].t>>a[i].c;
}
sort(a+1,a+m+1,cmp);
ll num=0,s=0;
for(i=1;i<=m;i++){
if(a[i].f==0){
continue;
}
if(b[a[i].f]==-1){
num++;
b[a[i].f]=a[i].c;
s=s+a[i].c;
}
else{
if(b[a[i].f]>a[i].c){
s=s-b[a[i].f];
b[a[i].f]=a[i].c;
s=s+a[i].c;
}
}
if(num==n){
ans[a[i].d]=s;
}
}
num=0;s=0;
for(i=1;i<=MAXN;i++){
b[i]=-1;
ans1[i]=inf;
}
for(i=m;i>=1;i--){
if(a[i].t==0){
continue;
}
if(b[a[i].t]==-1){
num++;
b[a[i].t]=a[i].c;
s=s+a[i].c;
}
else{
if(b[a[i].t]>a[i].c){
s=s-b[a[i].t];
b[a[i].t]=a[i].c;
s=s+a[i].c;
}
if(num==n){
ans1[a[i].d]=s;
}
}
if(num==n){
ans1[a[i].d]=s;
}
}
for(i=1;i<=1000001;i++){
if(ans[i]!=inf) break;
}
j=i;
for(i=j+1;i<=1000001;i++){
ans[i]=min(ans[i-1],ans[i]);
}
for(i=1000001;i>=1;i--){
if(ans1[i]!=inf) break;
}
j=i;
for(i=j-1;i>=1;i--){
ans1[i]=min(ans1[i],ans1[i+1]);
}
ll res=inf;
for(i=1;i<=1000001;i++){
if(ans[i]==inf||ans1[i+k+1]==inf) continue;
res=min(ans[i]+ans1[i+k+1],res);
}
if(res==inf){
cout<<-1<<endl;
}
else{
cout<<res<<endl;
}
return 0;
}
总结
最终RANK:2
待提升
D题比赛时我并没有ac,补题时也在cf上wa了n遍,D题暴露出来最主要的问题就是对于多个数据的处理方面,后面是听从大佬意见使用结构体存储航班的四个数据,这个小技巧以后也可以使用.
FIGHTING!
2017年9月7日