/*
杭電題目第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;
}
文章標題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.