归并排序
模板
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],temp[N];
void msort(int l,int r)
{
if(l>=r) return ;
int mid=l+r>>1;
msort(l,mid);
msort(mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r)
if(a[i]<=a[j])
temp[k++]=a[i++];
else temp[k++]=a[j++];
while(i<=mid)
temp[k++]=a[i++];
while(j<=r)
temp[k++]=a[j++];
for(int i=l,j=0;i<=r;) a[i++]=temp[j++];
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
msort(0,n-1);
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
return 0;
}
2.移动距离
公式很容易推的
#include <bits/stdc++.h>
using namespace std;
int main()
{
int cnt1,cnt2;
int w,a,b;
cin>>w>>a>>b;
int res=abs((w+a-1)/w-(w+b-1)/w);
if(((w+a-1)/w)%2==1)
{
cnt1=a%w;
if(cnt1==0)
cnt1=w;
}
else if(((w+a-1)/w)%2==0)
{
cnt1=w-a%w+1;
if(cnt1==w+1)
cnt1=1;
}
if(((w+b-1)/w)%2==1)
{
cnt2=b%w;
if(cnt2==0)
cnt2=w;
}
else if(((w+b-1)/w)%2==0)
{
cnt2=w-b%w+1;
if(cnt2==w+1)
cnt2=1;
}
cout<<res+abs(cnt1-cnt2)<<endl;
return 0;
}
3.日期问题
注意想一种比较好的思路 并且注意一下一个知识点 格式化输入补前导零printf("%0xd",a);
这个就是如果a不够x位 就在前面补前导零
#include <cstdio>
#include <iostream>
using namespace std;
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check_valid(int year, int month, int day)
{
if (month == 0 || month > 12) return false;
if (day == 0) return false;
if (month != 2)
{
if (day > days[month]) return false;
}
else
{
int leap = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
if (day > days[month] + leap) return false;
}
return true;
}
int main()
{
int a, b, c;
scanf("%d/%d/%d", &a, &b, &c);
for (int date = 19600101; date <= 20591231; date ++ )
{
int year = date / 10000, month = date % 10000 / 100, day = date % 100;
if (check_valid(year, month, day))
{
if ((year % 100 == a && month == b && day == c) || // 年/月/日
(month == a && day == b && year % 100 == c) || // 月/日/年
(day == a && month == b && year % 100 == c) ) //月/日/年
printf("%d-%02d-%02d\n", year, month, day); //补前导0
}
}
return 0;
}
4.航班时间
去乘起飞时间+航行时间+时差=去乘降落时间 (公式一)
回程起飞时间+航行时间-时差=回程降落时间 (公式二)
求:航行时间
已知:去乘起飞时间,回程起飞时间,去乘降落时间,回程降落时间
根据公式一+公式二:
去乘起飞时间+回程起飞时间+2*航行时间=去乘降落时间+回程降落时间
航行时间=(去乘降落时间-去乘起飞时间+回程降落时间-回程起飞时间)/2
用scanf格式化输入 很舒服就能做对了
#include<bits/stdc++.h>
using namespace std;
int getTime(void)
{
int h1,m1,s1,h2,m2,s2,d=0;
scanf("%d:%d:%d %d:%d:%d (+%d)",&h1,&m1,&s1,&h2,&m2,&s2,&d);
int time=d*24*3600+h2*3600+m2*60+s2-(h1*3600+m1*60+s1);
return time;
}
int main()
{
int t;
scanf("%d",&t);
for(int i = 0; i < t; i++)
{
int time1=getTime();
int time2=getTime();
int t=(time1+time2)/2;
printf("%02d:%02d:%02d\n", t/3600, t/60%60, t%60);
}
return 0;
}
5.外卖店优先级
按id为第一关键字排序 先判断一个店能不能ans++,再判断第二个 第三个.....
然后注意一点细节就好了
cur初始化的时候 观察循环是从1到m的 所以m[0]的订单是没有加上的 所以cur初始化为2是加上m[0] 然后后面的每一步都是加上集合中的第一个 所有一直初始化为2
然后diff是有边界有特殊情况的
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct message
{
int t, id;
bool operator < (const message& m)
{
return id < m.id || id == m.id && t < m.t;
}
}a[N];
int main()
{
int ans=0;
int n,m,t;
cin>>n>>m>>t;
for(int i=0;i<m;i++)
cin>>a[i].t>>a[i].id;
sort(a,a+m);
int cur=2;
bool st=false;
for(int i=1;i<=m;i++)
{
if(a[i].id!=a[i-1].id)
{
if(st&&cur-(t-a[i-1].t)>3) ans++;
st=false;
cur=2;
}
else
{
int diff=a[i].t-a[i-1].t-1;
if(diff==-1) diff=0;
cur=max(0,cur-diff);
if(cur<=3) st=false;
cur+=2;
if(cur>5) st=true;
}
}
cout<<ans<<endl;
return 0;
}
6.逆序对数量
归并排序可以直接算的 cnt+=mid-i+1;理解归并排序原理就知道为什么了
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],temp[N];
int cnt;
void msort(int l,int r)
{
if(l>=r) return ;
int mid=l+r>>1;
msort(l,mid);
msort(mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r)
if(a[i]<=a[j])
temp[k++]=a[i++];
else
{
cnt+=mid-i+1;
temp[k++]=a[j++];
}
while(i<=mid)
temp[k++]=a[i++];
while(j<=r)
temp[k++]=a[j++];
for(int i=l,j=0;i<=r;) a[i++]=temp[j++];
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
msort(0,n-1);
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
return 0;
}