从零单排8

一会儿换教室,总结一下

刚刚的任务

6. 学会分治策略
7. 排序算法
a) 归并排序  hdu 1425
b) 快速排序  hdu 1425
c) 计数排序  hdu 1425(不知道这里用hash算不算计数排序。。。总感觉hash是简化版的计数排序。。。好吧我是弱菜。。)
8. 数论
a) 扩展欧几里德算法  hdu 1576 2699
b) 求逆元  ..同上。。。
c) 同余方程 ..为什么看到同余方程我只会想到快速幂。。
d) 中国剩余定理  hdu 1788..(这题真的是中国剩余定理么。。。)

排序是老内容,直接拖我一直在学习的一个人的算法模版,他的好多算法写的真好~

他的主页:http://my.csdn.net/liufeng_king

排序算法多写几遍自然熟能生巧~

对于数论部分的内容。。

唉。。

数学这种东西会了就是会了,不会就是不会...

这种东西只能学知识点搜应用然后记住下一次遇到同类型题套公式。。。

加油吧。。


题解:

hdu 1425:http://acm.hdu.edu.cn/showproblem.php?pid=1425

#include<iostream>
using namespace std;
int a[1000005];
int b[1000005];
void Merge(int c[],int d[],int l,int m,int r)
{
	int i=l;
	int j=m+1;
	int k=l;
	while((i<=m)&&(j<=r))
	{
		if(c[i]<=c[j])
		{
			d[k++]=c[i++];
		}
		else
		{
			d[k++]=c[j++];
		}
	}
	if(i>m)
	{
		for(int q=j;q<=r;q++)
		{
			d[k++]=c[q];
		}
	}
	else
	{
		for(int q=i;q<=m;q++)
		{
			d[k++]=c[q];
		}
	}
}
void MergeSort(int a[],int left,int right)
{
	if(left<right)
	{
		int i=(left+right)/2;
		MergeSort(a,left,i);
		MergeSort(a,i+1,right);
		Merge(a,b,left,i,right);
		for(int g=left;g<=right;g++)
		{
			a[g]=b[g];
		}
	}
}
int Partition(int a[],int p,int r)
{
	int i=p;
	int j=r+1;
	int x=a[p];
	while(1)
	{
		while(a[++i]<x&&i<r)
			;
		while(a[--j]>x)
			;
		if(i>=j)
		{
			break;
		}
		swap(a[i],a[j]);
	}
	a[p]=a[j];
	a[j]=x;
	return j;
}
void QuickSort(int a[],int p,int r)
{
	if(p<r)
	{
		int q=Partition(a,p,r);
		QuickSort(a,p,q-1);
		QuickSort(a,q+1,r);
	}
}
int main()
{
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
//		QuickSort(a,0,n-1);
		MergeSort(a,0,n-1);
		for(int i=n-1;i>n-m-1;i--)
		{
			printf("%d",a[i]);
			if(i!=n-m)
			{
				printf(" ");
			}
		}
		printf("\n");
	}
	system("pause");
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define MAXN 1000005
#define N 500000
using namespace std;

bool hash[MAXN];

int main(void)
{
	int n,m;
	while(cin>>n>>m)
	{
		memset(hash,0,sizeof(hash));
		for(int i=1;i<=n;i++)
		{
			int a;
			scanf("%d",&a);
			hash[a+N]=true;//数组下标非负 
		}
		int total=0;
		for(int i=MAXN;i>=1;i--)
		{
			if(hash[i]==true)
			{
				total++;
				if(total==m)
				{
					printf("%d\n",i-N);
					break;
				}
				else printf("%d ",i-N);
			}
		}
	}
	system("pause");
}

hdu 1576: http://acm.hdu.edu.cn/showproblem.php?pid=1576

/*
扩展欧几里德算法应用,
这篇题解讲的非常详细之极!!!
http://blog.csdn.net/lulipeng_cpp/article/details/7612490
解决该题的关键是:

1、了解扩展欧几里德算法,可以运用其解出gcd(a,b)=ax1+by1中的x1、y1的值

2、由题可得以下内容:

n=A%9973,则n=A-A/9973*9973。又A/B=x,则A=Bx。所以Bx-A/9973*9973=n。即Bx-9973y=n。

到这里我们可以发现:只要求出x的值,即可算出x%9973,也就是(A/B)%9973了。顺利解决了!

3、题目关键转到如何求出x了。题目的输入是n和B,利用扩展欧几里德算法可求出gcd(B,9973)=Bx1+9973y1=1的x1。

等式两边同乘以n,得B(nx1)-9973(-ny1)=n。可知nx1就是Bx-9973y=n的解了!!!即x=nx1。

4、对于第三部得到的x可能是负数,由题这显然是不正确的。

可以做这样的转化:(x%9973+9973)%9973
*/
#include<iostream>
#define M 9973
using namespace std;
int x,y;
void extendGcd(int a,int b)
{
	if(b==0)
	{
		x=1;
		y=0;
		return ;
	}
	else
	{
		extendGcd(b,a%b);
		int temp=x;
		x=y;
		y=temp-a/b*y;
	}
}
		
int main()
{
	int T;
	int n,b;
	cin>>T;
	while(T--)
	{
		x=y=0;
		cin>>n>>b;
		extendGcd(b,M);
		x=x*n;
		int ans=(x%M+M)%M;
		cout<<ans<<endl;
	}
	system("pause");
	return 0;
}
		
		

hdu 2699: http://acm.hdu.edu.cn/showproblem.php?pid=2699

/*
裸扩展欧几里德
*/
#include<iostream>
using namespace std;
long long x,y,temp,gcd;
int extendGcd(long long a,long long b)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	else
	{
		long long d=extendGcd(b,a%b);
		temp=x;
		x=y;
		y=temp-a/b*y;
		return d;
	}
}
int main()
{
	long long a,b;
	while(cin>>a>>b)
	{
		x=0;
		y=0;
		temp=0;
		gcd=extendGcd(a,b);
		if(gcd!=1)
		{
			cout<<"sorry"<<endl;
		}
		else
		{
			while(x<0)
			{
				x=x+b;
				y=y-a;
			}
			cout<<x<<" "<<y<<endl;
		}
	}
	system("pause");
	return 0;
}
			
		

hdu 1788: http://acm.hdu.edu.cn/showproblem.php?pid=1788

/*
百度说这题是关于中国剩余定理的?
。。
为什么做了半天感觉就是求n个数的最小公倍数。。
*/
#include<iostream>
using namespace std;
long long gcd(long long a,long long b)
{
	return b==0?a:gcd(b,a%b);
}
int main()
{
	int n,m;
	while(cin>>n>>m,n!=0&&m!=0)
	{
		long long ans=1;
		long long temp;
		for(int i=0;i<n;i++)
		{
			cin>>temp;
			ans=(ans*temp)/gcd(ans,temp);
		}
		cout<<ans-m<<endl;
	}
	system("pause");
	return 0;
}

终于要开始做博弈题啦~~~话说刚接触编程的时候参加比赛自己只会做简单的博弈题。。。找规律什么的。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值