归并排序(从小到大)
void merge_sort(int *A,int x,int y,int *T)
{
if(y-x>1)
{
int m=x+(y-x)/2; //划分
int p=x,q=m,i=x;
merge_sort(A,x,m,T); //递归求解
merge_sort(A,m,y,T); //递归求解
while(p<m||q>y)
{
if(q>=y||(p<m&&A[p]<=A[q]))
T[i++]=A[p++]; //从左半数组复制到临时空间
else T[i++]=A[q++]; //从右半数组复制到临时空间
}
for(i=x;i<y;i++) A[i]=T[i]; //从辅助空间复制回原数组
}
}
1325:【例7.4】 循环比赛日程表
【题目描述】
设有NN个选手进行循环比赛,其中N=2M2M,要求每名选手要与其他N−1N−1名选手都赛一次,每名选手每天比赛一次,循环赛共进行N−1N−1天,要求每天没有选手轮空。
【输入】
输入:MM。
【输出】
输出:表格形式的比赛安排表。一行各数据间用一个空格隔开。
【输入样例】
3
【输出样例】
1 2 3 4 5 6 7 8
2 1 4 3 6 5 8 7
3 4 1 2 7 8 5 6
4 3 2 1 8 7 6 5
5 6 7 8 1 2 3 4
6 5 8 7 2 1 4 3
7 8 5 6 3 4 1 2
8 7 6 5 4 3 2 1
#include<iostream>
#define N 1025
using namespace std;
int m,n,k=1,half=1,i,j,f[N][N];
int main()
{
cin>>m;
n=1<<m;
f[0][0]=1;
while(k<=m)
{
for(i=0;i<half;i++)
for(j=0;j<half;j++)
f[i][j+half]=f[i][j]+half;
for(i=0;i<half;i++)
for(j=0;j<half;j++)
{
f[i+half][j]=f[i][j+half];
f[i+half][j+half]=f[i][j];
}
half*=2;
k++;
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
cout<<f[i][j]<<" ";
cout<<endl;
}
return 0;
}
1326:【例7.5】 取余运算(mod)
提交数: 6816 通过数: 3092
【题目描述】
输入b,p,kb,p,k的值,求bpmodkbpmodk的值。其中b,p,k×kb,p,k×k为长整型数。
【输入】
输入b,p,kb,p,k的值。
【输出】
求bpmodkbpmodk的值。
【输入样例】
2 10 9
【输出样例】
2^10 mod 9=7
#include<iostream>
#include<cstdio>
using namespace std;
int b,p,k,a;
int f(int p)
{
if(p==0) return 1;
int tmp=f(p/2)%k;
tmp=(tmp*tmp)%k;
if(p%2==1) tmp=(tmp*(b%k))%k;
return tmp;
}
int main()
{
cin>>b>>p>>k;
int tmpb=b;
b%=k;
cout<<tmpb<<"^"<<p<<" mod "<<k<<"="<<f(p)<<endl;
return 0;
}
1327:【例7.6】黑白棋子的移动
【题目描述】
有2n个棋子(n≥4)排成一行,开始位置为白子全部在左边,黑子全部在右边,如下图为n=5的情形:
○○○○○●●●●●
移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,成为:
○●○●○●○●○●
任务:编程打印出移动过程。
【输入】
输入n。
【输出】
移动过程。
【输入样例】
7
【输出样例】
#include<iostream>
using namespace std;
int n,step,ans;
char ch[101];
void print()
{
int i;
if(step<10) cout<<"step "<<step<<":";
else cout<<"step"<<step<<":";
if(step==1)
{
ch[2*n+2]='*';
ch[2*n+1]='o';
}
for(i=1;i<=2*n+2;i++)
cout<<ch[i];
cout<<endl;
step++;
}
void init(int n)
{
int i;
step=0;
ans=2*n+2;
for(i=1;i<=n;i++)
ch[i]='o';
for(i=n+1;i<=2*n;i++)
ch[i]='*';
for(i=2*n+1;i<=2*n+2;i++)
ch[i]='-';
print();
}
void move(int k)
{
int j;
for(j=0;j<=1;j++)
{
ch[ans+j]=ch[k+j];
ch[k+j]='-';
}
ans=k;
print();
}
void change(int n)
{
int i,k;
if(n==4)
{
move(4);
move(8);
move(2);
move(7);
move(1);
}
else
{
move(n);
move(2*n-1);
change(n-1);
}
}
int main()
{
cin>>n;
init(n);
change(n);
return 0;
}
1328:【例7.7】光荣的梦想
【题目描述】
Prince对他在这片大陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯。在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界、保卫这里的平衡与和谐。在那个时代,平衡是个梦想。因为有很多奇异的物种拥有各种不稳定的能量,平衡瞬间即被打破。KB决定求助于你,帮助他完成这个梦想。
一串数列即表示一个世界的状态。
平衡是指这串数列以升序排列。而从一串无序数列到有序数列需要通过交换数列中的元素来实现。KB的能量只能交换相邻两个数字。他想知道他最少需要交换几次就能使数列有序。
【输入】
第一行为数列中数的个数n,第二行为n ≤ 10000个数。表示当前数列的状态。
【输出】
输出一个整数,表示最少需要交换几次能达到平衡状态。
【输入样例】
4
2 1 4 3
【输出样例】
2
#include<iostream>
#include<cstdio>
using namespace std;
int temp[10001],a[10001],tot=0;
void asort(int left,int right)
{
if(left==right) return;
int mid=(left+right)/2;
asort(left,mid);
asort(mid+1,right);
int p=left,i=left,j=mid+1;
while(i<=mid&&j<=right)
{
if(a[i]>a[j])
{
tot=tot+mid-i+1;
temp[p++]=a[j++];
}
else temp[p++]=a[i++];
}
while(i<=mid) temp[p++]=a[i++];
while(j<=right) temp[p++]=a[j++];
for(i=left;i<=right;i++)
a[i]=temp[i];
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
asort(1,n);
printf("%d",tot);
return 0;
}
1234:2011
提交数: 4617 通过数: 1969
【题目描述】
已知长度最大为200位的正整数n,请求出2011n的后四位。
【输入】
第一行为一个正整数k,代表有k组数据(k≤200),接下来的k行,每行都有一个正整数n,n的位数≤200。
【输出】
每一个n的结果为一个整数占一行,若不足4位,去除高位多余的0。
【输入样例】
3
5
28
792
【输出样例】
1051
81
5521
TLE代码
#include<iostream>
#include<cmath>
using namespace std;
int n,ans=1,t;
int main()
{
cin>>t;
while(t--)
{
ans=1;
cin>>n;
for(int i=1;i<=n;i++)
{
ans*=2011;
ans%=10000;
}
cout<<ans%10000<<endl;
}
}
AC代码
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
int ans=1,t,len,cnt,i;
char ch[205];
int main()
{
cin>>t;
while(t--)
{
ans=0;
cnt=2011;
cin>>ch;
len=strlen(ch);
for(i=len-4;i<len;i++)
{
if(i>=0)
ans=ans*10+ch[i]-'0';
}
for(i=1;i*2<=ans;i*=2)
{
cnt*=cnt;
cnt%=10000;
}
for(;i<ans;i++)
{
cnt*=2011;
cnt%=10000;
}
cout<<cnt%10000<<endl;
}
return 0;
}
1240:查找最接近的元素
【题目描述】
在一个非降序列中,查找与给定值最接近的元素。
【输入】
第一行包含一个整数n,为非降序列长度。1 ≤ n ≤ 100000。
第二行包含n个整数,为非降序列各元素。所有元素的大小均在0-1,000,000,000之间。
第三行包含一个整数m,为要询问的给定值个数。1 ≤ m ≤ 10000。
接下来m行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在0-1,000,000,000之间。
【输出】
m行,每行一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。
【输入样例】
3
2 5 8
2
10
5
【输出样例】
8
5
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int n,m,a[100005],s,half,Left,Right;
bool flag=false;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
cin>>m;
while(m--)
{
cin>>s;
Left=1;
Right=n;
half=(Left+Right)/2;
flag=false;
while(Right-Left>1)
{
if(a[half]>s)
{
Right=half;
half=(Left+Right)/2;
}
else if(a[half]<s)
{
Left=half;
half=(Left+Right)/2;
}
else
{
flag=true;
break;
}
}
if(flag) cout<<a[half]<<endl;
else if(fabs(s-a[Left])<=fabs(s-a[Right])) cout<<a[Left]<<endl;
else cout<<a[Right]<<endl;
}
return 0;
}