/*
杭电题目第10页:http://acm.hdu.edu.cn/listproblem.php?vol=10 最下面的中文题
杭电题目第11页:http://acm.hdu.edu.cn/listproblem.php?vol=11 除2089外的所有的中文题
*/
//排序
#include <stdio.h>
//冒泡
void sort_bubble(int* a, int n)
{
int i, j, t;
for (i=0; i<n-1; i++){
for (j=0; j<n-1; j++){
if (a[j] > a[j+1]){
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
}
//选择
void sort_select(int* a, int n)
{
int i, j, t;
int k;
for (i=0; i<n; i++){
k=i;
for (j=i+1; j<n; j++){
if (a[j] < a[k]) k = j;
}
t = a[k];
a[k] = a[i];
a[i] = t;
}
}
//快速排序
void qp(int* a, int n, int l, int r)
{
int i, j, k, t;
i = l;
j = r;
k = a[(i+j) >> 1];
while (i <= j){
while (a[i] < k) i++;
while (a[j] > k) j--;
if (i <= j){
t = a[i];
a[i] = a[j];
a[j] = t;
i++;
j--;
}
}
if (i < r) qp(a, n, i, r);
if (l < j) qp(a, n, l, j);
}
//归并排序
int r[100];
void msort(int* a, int n, int s, int t)
{
int m, i, j, k;
if (s == t) return;
m = (s + t) >> 1;
msort(a, n, s, m);
msort(a, n, m+1, t);
i = s; j = m+1; k = s;
while (i<=m && j<=t){
if (a[i] < a[j]){
r[k] = a[i];
i++;
k++;
}else{
r[k] = a[j];
j++;
k++;
}
}
while (i <= m){
r[k] = a[i];
i++;
k++;
}
while (j <= t){
r[k] = a[j];
j++;
k++;
}
for (i=s; i<=t; i++) a[i] = r[i];
}
int main()
{
int a[100] = {0};
int n;
int i;
scanf("%D", &n);
for (i=0; i<n; i++) scanf("%d", &a[i]);
sort_bubble(a, n);
for (i=0; i<n; i++) printf("%d ", a[i]);
return 0;
}
//KMP(改进的字符串匹配算法)
#include<stdio.h>
#include<string.h>
char T[10000];
char P[200];
int f[210];
void getFail(char *P, int *f)
{
int m = strlen(P);
f[0] = f[1] = 0;
for (int i=1; i<m; i++)
{
int j = f[i];
while (j && P[i] != P[j]) j = f[j];
f[i+1] = P[i] == P[j] ? j+1 : 0;
}
}
int Find(char *T, char *P, int *f)
{
int n = strlen(T), m = strlen(P);
getFail(P, f);
int j = 0;
for (int i=0; i<n; i++)
{
while (j && T[i] != P[j]) j = f[j];
if (T[i] == P[j]) j++;
if (j == m)
return i-m+1; //找到字符串,返回字符串的起始位置
}
return -1; //没有找到,返回-1
}
int main()
{
scanf("%s", T); //在T里面找P
scanf("%s", P);
printf("%s在%s中第一次出现的位置是:%d\n", P, T, Find(T, P, f));
return 0;
}
桶排序
#include <stdio.h>
int cnt[10000];
int main()
{
int n;
int i, j;
int x;
printf("请输入数据个数:");
scanf("%d", &n);
printf("请输入数据:");
for (i=0; i<n; i++){
scanf("%d", &x);
cnt[x]++;
}
printf("排序后的数据如下:");
for (i=0; i<10000; i++){
for (j=0; j<cnt[i]; j++) printf("%d ", i);
}
printf("\n");
return 0;
}
堆排序
#include<stdio.h>
int a[10000];
int n,tot;
int down(int i)
{
int j,t,tmp;
tmp=tot>>1;
while (i<=tmp)
{
j=2*i;
if ((j<tot)&&(a[j+1]<a[j])) j++;
if (a[i]>a[j])
{
t=a[i]; a[i]=a[j]; a[j]=t;
i=j;
}
else break;
}
}
int main()
{
int i,t,tmp;
scanf("%d",&n);
for (i=1;i<=n;i++) scanf("%d",&a[i]);
tot=n;
tmp=n>>1;
for (i=tot;i>=1;i--) down(i);
for (i=1;i<=n;i++)
{
t=a[1]; a[1]=a[tot]; a[tot]=t;
tot--;
down(1);
}
for (i=n;i>1;i--) printf("%d ",a[i]); printf("%d",a[i]);
return 0;
}
基数排序:https://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html
#include <stdio.h>
int maxbit(int data[], int n) //辅助函数,求数据的最大位数
{
int d = 1; //保存最大的位数
int p = 10;
for(int i = 0; i < n; ++i)
{
while(data[i] >= p)
{
p *= 10;
++d;
}
}
return d;
}
void radixsort(int data[], int n) //基数排序
{
int d = maxbit(data, n);
int tmp[1000];
int count[10]; //计数器
int i, j, k;
int radix = 1;
for(i = 1; i <= d; i++) //进行d次排序
{
for(j = 0; j < 10; j++)
count[j] = 0; //每次分配前清空计数器
for(j = 0; j < n; j++)
{
k = (data[j] / radix) % 10; //统计每个桶中的记录数
count[k]++;
}
for(j = 1; j < 10; j++)
count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶
for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
{
k = (data[j] / radix) % 10;
tmp[count[k] - 1] = data[j];
count[k]--;
}
for(j = 0; j < n; j++) //将临时数组的内容复制到data中
data[j] = tmp[j];
radix = radix * 10;
}
}
int main()
{
int a[100];
int n;
int i;
scanf("%d",&n);
for (int i=0; i<n; i++) scanf("%d", &a[i]);
radixsort(a, n);
for (i=0; i<n; i++) printf("%d ", a[i]);
return 0;
}
//n皇后问题
// N皇后问题是一个经典的问题,在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行、同一列、同一斜线上的皇后都会自动攻击)
/*在n*n的棋盘中放置n个皇后,要求所有的皇后都不在同一行、同一列、同一对角线*/
#include <stdio.h>
int n;
int cnt;
int r[11];
short low[11], left[22], right[22];
void dfs(int deep)
{
int i;
if (deep > n){
cnt++;
printf("方案%d:\n", cnt);
for (i=1; i<=n; i++) printf("第%d行放在第%d列\n", i, r[i]);
return;
}
for (i=0; i<n; i++){
if (!low[i] && !left[deep+i] && !right[deep-i+10]){
low[i] = left[deep+i] = right[deep-i+10] = 1;
r[deep] = i;
dfs(deep+1);
low[i] = left[deep+i] = right[deep-i+10] = 0;
r[deep] = 0;
}
}
}
int main()
{
printf("请输入皇后的数量:");
scanf("%d", &n);
dfs(1);
return 0;
}
//自然数分解
/*输入一个自然数,把它分解成若干个自然数的和,输出所有方案*/
#include <stdio.h>
int n;
int a[100];
void dfs(int deep, int start, int last)
{
int i;
if (last == 0){
printf("%d=", n);
for (i=0; i<deep-1; i++) printf("%d+", a[i]);
printf("%d\n", a[deep-1]);
return;
}
for (i=start; i<=last; i++){
a[deep] = i;
dfs(deep+1, i, last-i);
a[deep] = 0;
}
}
int main()
{
printf("请输入要分解的自然数:");
scanf("%d", &n);
dfs(0, 1, n);
return 0;
}
//斐波那契——矩阵乘法
//跳台阶,实质:斐波那契数列
/*跳台阶:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
设f[i]为到达第i级台阶的方案数,那么
f[0]=1(在地面上),
f[1]=1,
f[2]=2(直接从地面跳到第二级或者先到第一级再到第二级),
f[3]=f[2]+f[1],
f[4]=f[3]+f[2],
……
f[i]=f[i-1]+f[i-2]
斐波那契数列*/
#include<stdio.h>
int f[3][3],a[3][3],b[3][3],c[3][3];
int n;
const int MO=15746;
void ksm(int t)
{
int i,j,k;
a[1][1]=1; a[1][2]=1;
a[2][1]=1; a[2][2]=0;
f[1][1]=1; f[1][2]=1;
f[2][1]=1; f[2][2]=0;
while (t>0)
{
if (t%2==1)
{
for (i=1;i<=2;i++)
for (j=1;j<=2;j++)
for (k=1;k<=2;k++)
c[i][j]=(c[i][j]+f[i][k]*a[k][j])%MO;
for (i=1;i<=2;i++)
for (j=1;j<=2;j++)
{
f[i][j]=c[i][j];
c[i][j]=0;
}
}
t=t>>1;
for (i=1;i<=2;i++)
for (j=1;j<=2;j++)
for (k=1;k<=2;k++) c[i][j]=(c[i][j]+a[i][k]*a[k][j])%MO;
for (i=1;i<=2;i++)
for (j=1;j<=2;j++)
{
a[i][j]=c[i][j];
c[i][j]=0;
}
}
}
int main()
{
int i,j,k;
scanf("%d",&n);
ksm(n-3);
b[1][1]=2;b[1][2]=1;
for (j=1;j<=2;j++)
for (k=1;k<=2;k++) c[1][j]=(c[1][j]+b[1][k]*f[k][j])%MO;
if (n==1) printf("1");
else
{
if (n==2) printf("2");
else printf("%d",c[1][1]);
}
return 0;
}
//丑数
/*把只包含因子2、3和5的数称作丑数(Ugly Number)。
例如6、8都是丑数,但14不是,因为它包含因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。*/
#include <iostream>
#include <cstdio>
using namespace std;
#define min(a,b) ((a)<(b)?(a):(b))
#define min4(a,b,c,d) min(min(a,b),min(c,d))
int a[5850];
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int n=1;
int p2,p3,p5,p7;
p2=p3=p5=p7=1;
a[1]=1;
while(n<5843)//枚举5842个丑数,放在数组a里。
{
a[++n]=min4(2*a[p2],3*a[p3],5*a[p5],7*a[p7]);//从现在枚举的4个丑数里,先选择小的放在a里。
if(a[n]==2*a[p2])p2++;//如果a[n]==2*a[p2],2*a[p2]可能是吧a[n]枚举出的数,这样p2++,也可能是重复的枚举,这样也是p2++,总之p2++。
if(a[n]==3*a[p3])p3++;//同理。
if(a[n]==5*a[p5])p5++;//同理。
if(a[n]==7*a[p7])p7++;//同理。
}
while(scanf("%d",&n)&&n)
{
printf("%d\n",a[n]);//要谁找谁。
}
return 0;
}
//求逆序对的个数
#include<stdio.h>
int a[10000];
int r[10000];
int n,ans;
void msort(int s,int t)
{
int m,i,j,k;
if (s==t) return;
m=(s+t)>>1;
msort(s,m);
msort(m+1,t);
i=s; j=m+1; k=s;
while ((i<=m)&&(j<=t))
{
if (a[i]>a[j])
{
r[k]=a[i];
i++;
k++;
ans+=t-j+1;
}
else
{
r[k]=a[j];
j++;
k++;
}
}
while (i<=m)
{
r[k]=a[i];
i++;
k++;
}
while (j<=t)
{
r[k]=a[j];
j++;
k++;
}
for (i=s;i<=t;i++) a[i]=r[i];
}
int main()
{
int i;
printf("请输入数列的长度:");
scanf("%d",&n);
printf("请输入数列中的每一个元素,用空格隔开:");
for (i=1;i<=n;i++) scanf("%d",&a[i]);
msort(1,n);
for (i=1;i<n;i++) printf("%d ",a[i]);
printf("%d\n",a[i]);
printf("%d",ans);
return 0;
}
//链表反转
/*输入一个数列,存到链表里面,然后把链表中节点前后反转,使首尾对调,然后输出*/
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
node* next;
};
node* head1;
node* tail1;
node* head2;
node* tail2;
int main()
{
int n, m;
int i;
int x;
node* temp; //添加节点时的暂存节点
node* p; //链表的遍历元素
node* q; //链表的遍历元素
//链表的head和tail都不存放数据
head1 = (node*)malloc(sizeof(node));
tail1 = (node*)malloc(sizeof(node));
head1->next = tail1;
tail1->next = NULL;
p = head1;
q = tail1;
printf("请输入链表的长度:");
scanf("%d", &n);
printf("请输入每一个整数数据,用空格隔开:");
for (int i=0; i<n; i++){
scanf("%d", &x);
temp = (node*)malloc(sizeof(node));
temp->data = x;
q = p->next;
p->next = temp;
temp->next = q;
p = p->next;
}
tail2 = (node*)malloc(sizeof(node));
tail2->next = NULL;
temp = tail2;
p = head1->next;
while (p != tail1){
q = p->next;
p->next = temp;
temp = p;
p = q;
}
head2 = (node*)malloc(sizeof(node));
head2->next = temp;
free(head1);
free(head2);
printf("逆转后的链表元素:");
p = head2->next;
while (p != tail2){
printf("%d ", p->data);
p = p->next;
}
printf("\n");
return 0;
}
//非递减链表的合并
/*给出两个不下降数列,存到链表里面,然后合并两个链表,要求合并之后任然是不下降序列*/
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
node* next;
};
//第一个链表的首和尾
node* head1;
node* tail1;
//第二个链表的首和尾
node* head2;
node* tail2;
int main()
{
int n, m;
int i;
int x;
node* temp; //添加节点时的暂存节点
node* p; //链表的遍历元素
node* q; //链表的遍历元素
node* t1; //链表的遍历元素
node* t2; //链表的遍历元素
//链表的head和tail都不存放数据
head1 = (node*)malloc(sizeof(node));
tail1 = (node*)malloc(sizeof(node));
head1->next = tail1;
tail1->next = NULL;
p = head1;
q = tail1;
printf("请输入第一个不下降链表的长度:");
scanf("%d", &n);
printf("请输入每一个整数数据,用空格隔开:");
for (int i=0; i<n; i++){
scanf("%d", &x);
temp = (node*)malloc(sizeof(node));
temp->data = x;
q = p->next;
p->next = temp;
temp->next = q;
p = p->next;
}
head2 = (node*)malloc(sizeof(node));
tail2 = (node*)malloc(sizeof(node));
head2->next = tail2;
tail2->next = NULL;
p = head2;
q = tail2;
printf("请输入第二个不下降链表的长度:");
scanf("%d", &m);
printf("请输入每一个整数数据,用空格隔开:");
for (int i=0; i<m; i++){
scanf("%d", &x);
temp = (node*)malloc(sizeof(node));
temp->data = x;
q = p->next;
p->next = temp;
temp->next = q;
p = p->next;
}
//把第二个链表合并到第一个链表中
t1 = head1;
t2 = head2->next;
while (t2!=tail2){
while (t1!=tail1 && t1->next->data<t2->data) t1 = t1->next;
p = t2;
t2 = t2->next;
q = t1->next;
t1->next = p;
p->next = q;
t1 = t1->next;
}
free(head2);
free(tail2);
printf("合并后的链表元素:");
p = head1->next;
while (p != tail1){
printf("%d ", p->data);
p = p->next;
}
printf("\n");
return 0;
}
//欧拉回路
//如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径(Euler path)
#include <stdio.h>
#define maxn 110
int v[maxn][maxn];
int vis[maxn][maxn];
int ans[maxn];
int n, m;
int s;
void eular(int x)
{
int i;
int y;
for (i=1; i<=v[x][0]; i++){
y = v[x][i];
if (!vis[x][y]){
vis[x][y] = 1;
vis[y][x] = 1;
eular(y);
ans[0]++;
ans[ans[0]] = y;
}
}
}
int main()
{
int i;
int x, y;
printf("请输入节点的数量:");
scanf("%d", &n);
printf("请输入边的数量:");
scanf("%d", &m);
printf("请输入欧拉回路的起点:");
scanf("%d", &s);
for (i=0; i<m; i++){
printf("请输入第%d条边的起点和终点:", i+1);
scanf("%d%d", &x, &y);
v[x][0]++;
v[x][v[x][0]] = y;
v[y][0]++;
v[y][v[y][0]] = x;
}
eular(s);
for (i=1; i<=ans[0]; i++) printf("%d ", ans[i]);
printf("\n");
return 0;
}
文章标题
最新推荐文章于 2022-06-12 17:07:04 发布