第一题:转圈游戏
一开始还没想到用快速幂(二分)的方法。
#include
#include
#include
#include
using namespace std;
int n;
long long dfn(int k){
if(k==1)return 10%n;
long long x=dfn(k>>1);
if(k&1){
return (x%n)*((x%n)*10)%n;//用x=dfn(k>>1),避免运算两次,优化。
}else return (x%n)*(x%n)%n;
}
main()
{
freopen("circle.in","r",stdin);
freopen("circle.out","w",stdout);
int m,k,x;long long sum;
scanf("%d%d%d%d",&n,&m,&k,&x);
sum=dfn(k);
sum=((sum*m)%n+x)%n;
printf("%I64d",sum);
}
第二题:火柴排队
首先判断出需要排序,排序后求逆序对,这里只用求一列数据就行。
#include
#include
#include
#include
#include
using namespace std;
struct node{
int num;int sum;
};node a[100005],b[100005];
int cmp(const node &x,const node &y){
return x.sum
int tot,T[100005],n,c[100005];
/*
void gui(int x,int y)
{
int m,i,j,k;
if(x==y)return;
m=(x+y)>>1;
gui(x,m);gui(m+1,y);
i=x;j=m+1;k=x;
while(i<=m&&j<=y){
if(c[i]<=c[j]){
T[k++]=c[i++];
}
else{
T[k++]=c[j++];
tot+=m-i+1;
}
}
while(i<=m)T[k++]=c[i++];
while(j<=y){
T[k++]=c[j++];
tot+=m-i+1;
}
for(i=x;i<=y;i++)
c[i]=T[i];
}
*/ 归并排序求逆序对;
main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
cin>>n;
int j;
for(j=1;j<=n;j++){cin>>a[j].sum;a[j].num=j;}
for(j=1;j<=n;j++){cin>>b[j].sum;b[j].num=j;}
sort(a+1,a+n+1,cmp);sort(b+1,b+n+1,cmp);
for(j=1;j<=n;j++)
c[a[j].num]=b[j].num;
gui(1,n);
cout<
不知道为什么测试后最后两个点过不了。
第三题:货车运输
只能说学过的东西忘得太快了,一开始觉得是动态规划,用Dijkstra算法来做,全错。。。
正解是用 最大生成树+贪心,这里用的并查集,过了%60。
先按边权值大小排序,每输入两个需要算的数据就按边权值大小合并边连接的两点,判断输入的数据是否在一个集合内,若在内则该边为解。
#include
#include
#include
using namespace std;
struct node{
int a,b,z;
};node pp[100005];
int father[100005];
int cmp(const node &a,const node &b){
return a.z>b.z;
}
int find(int x){
if(father[x]!=x)father[x]=find(father[x]);
return father[x];
}
void unionn(int x,int y){
father[find(y)]=find(x);
}
bool judge(int x,int y){
if(find(x)==find(y))return true;
return false;
}
int main()
{
freopen("truck.in","r",stdin);
freopen("truck.out","w",stdout);
int n,m,i,q;
cin>>n>>m;
for(i=1;i<=m;i++)
cin>>pp[i].a>>pp[i].b>>pp[i].z;
cin>>q;
sort(pp+1,pp+m+1,cmp);
while(q--){
for(i=1;i<=n;i++)father[i]=i;
int x,y;
scanf("%d%d",&x,&y);
int k=0;
for(i=1;i<=m;i++)
{
unionn(pp[i].a,pp[i].b);
if(judge(x,y)==true){
printf("%d\n",pp[i].z);k++;
break;
}
}
if(k==0)
printf("-1\n");
}
}