編程之美

1.1 cpu使用問題

#include <iostream>
#include <ctime>
#include <cmath>
#include <Windows.h>
using namespace std;

//第一種方式
void main()
{
	INT64 start=0;
	int busy=10;
	int idle=busy;
	cout<<"CPU使用率問題";
	while(true)
	{
		start=GetTickCount();
		while((GetTickCount()-start)<=busy);
		Sleep(idle);
	}
}

//第二種方式
int main()
{
	for(;;)
	{
		for(int i = 0; i < 9600000; i++);
		//for(int i = 0; i < 21360000; i++);//2.67Ghz 4核
		Sleep(10);
	}
	return 0;
}

//正玄曲線
const double SPLIT=0.01;
const int COUNT=200;
const double PI=3.14159265;
const int INTERVAL = 300;
void main()
{
	DWORD busy[COUNT],idle[COUNT];
	int half=INTERVAL/2;
	double radian=0.0;
	for(int i=0;i<COUNT;i++)
	{
		busy[i]=DWORD(sin(PI*radian)*half+half);
		idle[i]=INTERVAL-busy[i];
		radian+=0.01;
	}
	DWORD start=0;
	int j=0;
	while(true)
	{
		start=GetTickCount();
		j=j%COUNT;
		while((GetTickCount()-start)<=busy[j]);
		Sleep(idle[j]);
		j++;
	}
}
CPU核心運行週期數

#include <iostream>
using namespace std;
inline __int64 GetCPUTickCount()  
{  
	__asm  
	{  
		rdtsc;  
	}  
}
void main()
{
	cout<<"CPU核心運行週期數"<<GetCPUTickCount()<<endl;
	system("pause");
}


1.2 將帥問題

#include <iostream>
using namespace std;

//第一種方式
struct {
	unsigned char a:4;
	unsigned char b:4;
} i;
void main()
{
	for(i.a = 1; i.a <= 9; i.a++)
		for(i.b = 1; i.b <= 9; i.b++)
			if(i.a % 3 != i.b % 3)
				printf("A = %d, B = %d\n", i.a, i.b);
	system("pause");
}

//第二種方式
#define HALF_BITS_LENGTH 4
// 這個值是記憶存儲單元長度的一半,在這道題裏是4bit
#define FULLMASK 255
// 這個數字表示一個全部bit的mask,在二進制表示中,它是11111111。
#define LMASK (FULLMASK << HALF_BITS_LENGTH)
// 這個宏表示左bits的mask,在二進制表示中,它是11110000。
#define RMASK (FULLMASK >> HALF_BITS_LENGTH)
// 這個數字表示右bits的mask,在二進制表示中,它表示00001111。
#define RSET(b, n) (b = ((LMASK & b) ^ n))
// 這個宏,將b的右邊設置成n
#define LSET(b, n) (b = ((RMASK & b) ^ (n << HALF_BITS_LENGTH)))
// 這個宏,將b的左邊設置成n
#define RGET(b) (RMASK & b)
// 這個宏得到b的右邊的值
#define LGET(b) ((LMASK & b) >> HALF_BITS_LENGTH)
// 這個宏得到b的左邊的值
#define GRIDW 3
// 這個數字表示將帥移動範圍的行寬度。
#include <stdio.h>
#define HALF_BITS_LENGTH 4
#define FULLMASK 255
#define LMASK (FULLMASK << HALF_BITS_LENGTH)
#define RMASK (FULLMASK >> HALF_BITS_LENGTH)
#define RSET(b, n) (b = ((LMASK & b) ^ n))
#define LSET(b, n) (b = ((RMASK & b) ^ (n << HALF_BITS_LENGTH)))
#define RGET(b) (RMASK & b)
#define LGET(b) ((LMASK & b) >> HALF_BITS_LENGTH)
#define GRIDW 3
int main()
{
	unsigned char b;
	for(LSET(b, 1); LGET(b) <= GRIDW * GRIDW; LSET(b, (LGET(b) + 1)))
		for(RSET(b, 1); RGET(b) <= GRIDW * GRIDW; RSET(b, (RGET(b) + 1)))
			if(LGET(b) % GRIDW != RGET(b) % GRIDW)
				printf("A = %d, B = %d\n", LGET(b), RGET(b));
	system("pause");
	return 0;
}

1.8 電梯調度

#include <iostream>
using namespace std;
#define N 6
void main()
{
	int nPerson[N]={55,66,77,88,99,44};
	int N1=0,N2=0,N3=0;
	int nTargetFloor=0,nMinFloor=0,i;

	for (i=1,N1=0,N2=nPerson[0],N3=0;i<N;i++)
	{
		N3+=nPerson[i];
		nMinFloor+=nPerson[i+1]*i;
	}
	for (i=1;i<N;i++)
	{
		if (N1+N2<N3)
		{
			nTargetFloor=i+1;
			nMinFloor+=(N1+N2-N3);
			N1+=N2;
			N2=nPerson[i];
			N3-=nPerson[i];
		}
		else
			break;
	}
	cout<<"nTargetFloor "<<nTargetFloor<<"\nnMinFloor "<<nMinFloor<<endl;
	system("pause");
}


1.13 NIM兩堆石頭

#include <iostream>
#include <cmath>
using namespace std;
#define swap(x,y) ((x)^=(y),(y)^=(x),(x)^=(y))
void main()
{
	double a,b;
	a=(1+sqrt(5.0))/2;
	b=(3+sqrt(5.0))/2;
	int m,n;
	bool nim=false;
	cout<<"輸入兩堆石頭的書數目\n";
	cin>>m>>n;
	if (m==n)
		nim=true;
	if(n>m)
		swap(n,m);
	if (n-m==(long)floor(n*a))
		nim=false;
	else 
		nim=true;
	if(nim)
		cout<<"先取石頭玩家先贏\n";
	else
		cout<<"後取石頭玩家先贏\n";
	system("pause");
}


 1.16 24點遊戲

#include <iostream>
#include <string>
#include <cmath>
#include <stdlib.h>

using namespace std;

const double PRECISION = 1E-6;
const int COUNT_OF_NUMBER  = 4;
const int NUMBER_TO_CAL = 24;

double number[COUNT_OF_NUMBER];
string expression[COUNT_OF_NUMBER];

bool Search(int n)
{
    if (n == 1) {
    if ( fabs(number[0] - NUMBER_TO_CAL) < PRECISION ) {
        cout << expression[0] << endl;
        return true;
    } else {
        return false;
    }
}

for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
        double a, b;
        string expa, expb;

        a = number[i];
        b = number[j];
        number[j] = number[n - 1];

        expa = expression[i];
        expb = expression[j];
        expression[j] = expression[n - 1];

        expression[i] = '(' + expa + '+' + expb + ')';
        number[i] = a + b;
        if ( Search(n - 1) ) return true;

        expression[i] = '(' + expa + '-' + expb + ')';
        number[i] = a - b;
        if ( Search(n - 1) ) return true;

        expression[i] = '(' + expb + '-' + expa + ')';
        number[i] = b - a;
        if ( Search(n - 1) ) return true;


        expression[i] = '(' + expa + '*' + expb + ')';
        number[i] = a * b;
        if ( Search(n - 1) ) return true;

        if (b != 0) {
            expression[i] = '(' + expa + '/' + expb + ')';
            number[i] = a / b;
            if ( Search(n - 1) ) return true;
        }
        if (a != 0) {
            expression[i] = '(' + expb + '/' + expa + ')';
            number[i] = b / a;
            if ( Search(n - 1) ) return true;
        }

        number[i] = a;
        number[j] = b;
        expression[i] = expa;
        expression[j] = expb;
    }
}
    return false;
}

int main()
{
    for (int i = 0; i < COUNT_OF_NUMBER; i++) {
        char buffer[20];
        int  x;
        cin >> x;
        number[i] = x;
        itoa(x, buffer, 10);
        expression[i] = buffer;
    }

    if ( Search(COUNT_OF_NUMBER) ) {
        cout << "Success." << endl;
    } else {
        cout << "Fail." << endl;
    }
    return 0;
}


 

2.2階乘

void countZero()
{
    //100!末尾有多少個0
    int num,i,count=0;
    printf("Input a num as num!\n");
    scanf("%d",&num);
    for(i=5;i<=num;i+=5)
    {
        count++;
        if(!(num%25))
            count++;
    }
    printf("end of %d! has %d zero\n",num,count);
    count=0;
    while(num)
    {
        num/=2;
        count+=num;
    }
    printf("n! last one %d\n",count+1);//n!最低位1的位置 等同於求n!中有多少個質因數2
}

int main()
{
    countZero();//計算100!末尾0的個數
     return 0;
}

 

2.4 1的數目

int count1Int(int i)
{
    int numi=0;
    while(i!=0)
    {
        numi+=(i%10==1)?1:0;
        i/=10;
    }
    return numi;
}

void countOne()
{
    int i,n,count=0;
    printf("please input a number\n");
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        count+=count1Int(i);
    printf("count one %d",count);
}

int main()
{
    countOne();//一的數目

    return 0;
}

 

2.7 最大公約數最小公倍數求解


 

2.13 子數組最大乘積

#include <iostream>  
#include   <stdlib.h>   
#include   <stdio.h>   
using namespace  std;  

// 子數組的最大乘積  
int MaxProduct(int *a, int n)  
{  
	int maxProduct = 1; // max positive product at current position  
	int minProduct = 1; // min negative product at current position  
	int r = 1; // result, max multiplication totally  

	for (int i = 0; i < n; i++)  
	{  
		if (a[i] > 0)  
		{  
			maxProduct *= a[i];  
			minProduct = min(minProduct * a[i], 1);  
		}  
		else if (a[i] == 0)  
		{  
			maxProduct = 1;  
			minProduct = 1;  
		}  
		else // a[i] < 0  
		{  
			int temp = maxProduct;  
			maxProduct = max(minProduct * a[i], 1);  
			minProduct = temp * a[i];  
		}  

		r = max(r, maxProduct);  
	}  

	return r;  
}  

int main(int argc, char* argv[])  
{  
	int a[]={1, -2, -1,0,5};  
	int result = MaxProduct(a,5);  
	cout<<result<<endl;  
	system("pause");  
	return 0;  
}  

 

2.14 求子數組最大和

給一個數組,元素都是整數(有正數也有負數),尋找連續的元素相加之和爲最大的序列。

 

3.2 電話號碼對應英語單詞並實現從數字字典中查詢

#include <iostream>
using namespace std;
#define telLen 3

void match(char *words)
{
	char *word="YES YER";
	if(strstr(word,words))
	{
		printf("words %s\n",words);
	}
}
void main()
{
	char word[telLen+1]={0};//存儲生成的每個單詞
	char c[10][10]={"","","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"};//0到9數字所表示的字母
	int total[10]={0,0,3,3,3,3,3,4,3,4};//每個數字裏包含的字母個數
	int number[telLen]={9,3,7};//電話號碼
	int answer[10]={0};//數組記錄每個字母在它所在的數字鍵能代表的字符集中的偏移(索引),初始化爲0
	int i,j=0;
	while(true)
	{
		for (i=0;i<telLen;i++)
		{
			if(number[i]==1||number[i]==0)//忽略空格的影響
				break;
			else
			{
				printf("%c",c[number[i]][answer[i]]);
				word[i]=c[number[i]][answer[i]];
			}
		}
		word[telLen]='\0';
		match(word);//在數據字典中匹配
		printf("\n");
		int k=telLen-1;
		while(k>=0)
		{
			if (answer[k]<total[number[k]]-1)
			{
				answer[k]++;
				break;
			}
			else
			{
				answer[k]=0;
				k--;
			}
		}
		if (k<0)
			break;
	}
	system("pause");
}

 

 

3.6 編程判斷兩個鏈表是否相交


3.8 二叉樹中的一些問題


3.9 重建二叉樹

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Node
{
	char    chValue;
	struct Node    *lChild;
	struct Node    *rChild;
}Node;


//重建二叉樹
void Rebuild(char *pPreOrder , char *pInOrder , Node **pRoot , int nTreeLen)
{
	int  nLeftLen , nRightLen;
	char *pLeftEnd;
	Node *p;

	//邊界條件檢查
	if(!pPreOrder || !pInOrder || !pRoot)    return;   

	if(!(p = (Node *)malloc(sizeof(Node))))    return;
	p->chValue = *pPreOrder;    
	p->lChild = p->rChild = NULL;
	*pRoot = p;

	if(nTreeLen == 1)    return;

	//劃分左右子數
	pLeftEnd = pInOrder;
	while(*pLeftEnd != *pPreOrder)    pLeftEnd++;
	nLeftLen = (int)(pLeftEnd - pInOrder);
	nRightLen = nTreeLen - nLeftLen - 1;

	if(nLeftLen)    Rebuild(pPreOrder + 1 , pInOrder , &(p->lChild) , nLeftLen);
	if(nRightLen)   Rebuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen + 1 , &(p->rChild) , nRightLen);
}

//後序遍歷
void PostOrder(Node *p)
{
	if(p)
	{
		PostOrder(p->lChild);
		PostOrder(p->rChild);
		printf("%c",p->chValue);
	}
}

int main(void)
{
	char PreOrder[32] , InOrder[32];
	Node *pTree;

	//輸入先序和中序序列
	while(scanf("%s%s", PreOrder , InOrder) != EOF)//abdcef   dbaecf
	{
		Rebuild(PreOrder , InOrder , &pTree , strlen(PreOrder));
		PostOrder(pTree);
		printf("\n");
	}
	return 0;
}


4.9 數獨的構造

#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
/*問題:
構造一個9*9的方格矩陣,玩家要在每個方格中,分別填上1至9的任意一個數字,
讓整個棋盤每一列、每一行以及每一個3*3的小矩陣中的數字都不重複。
首先我們通過一個深度優先搜索來生成一個可行解,然後隨機刪除一定數量的數字,
以生成一個數獨。*/
#define LEN 9
#define CLEAR(a) memset((a), 0, sizeof(a))

int level[] = {30, 37, 45};

int grid[LEN+1][LEN+1];
int value[LEN+1];

void next(int &x, int &y)
{
    x++;
    if (x>9)
    {
        x = 1;
        y++;
    }
}

// 選擇下一個有效狀態
int pickNextValidValue(int x, int y, int cur)
{
    CLEAR(value);
    int i, j;
    for (i=1; i<y; i++)
        value[grid[i][x]] = 1;
    for (j=1; j<x; j++)
        value[grid[y][j]] = 1;
    int u = (x-1)/3*3 + 1;
    int v = (y-1)/3*3 + 1;
    for (i=v; i<v+3; i++)
        for (j=u; j<u+3; j++)
        {
            value[grid[i][j]] = 1;
        }
        for (i=cur+1; i<=LEN && value[i]; i++);
        return i;
}

void pre(int &x, int &y)
{
    x--;
    if (x<1)
    {
        x = 9;
        y--;
    }
}

int times = 0;

int main()
{
    int x, y, i, j;
    x = y = 1;
    // 深度搜索的迭代算法
    while (true)
    {
        times++;
        // 滿足成功結果
        if (y==LEN && x==LEN)
        {
            for (i=1; i<=LEN; i++)
            {
                for (j=1; j<=LEN; j++)
                    cout << grid[i][j] << " ";
                cout << endl;
            }
            cout << times << endl;
            break;
            //pre(x, y);
            //times = 0;
        }
        // 滿足失敗結果
        if (y==0)
            break;
        // 改變狀態
        grid[y][x] = pickNextValidValue(x, y, grid[y][x]);
        if (grid[y][x] > LEN)
        {
            // 恢復狀態
            grid[y][x] = 0;
            pre(x, y);
        }
        else
            // 進一步搜索
            next(x,y);
    }
    for (i=1; i<= level[2]; i++)
    {
        int ind = rand()%(LEN*LEN);
        grid[ind/LEN+1][ind%LEN] = 0;
    }
    for (i=1; i<=LEN; i++)
    {
        for (j=1; j<=LEN; j++)
            cout << grid[i][j] << " ";
        cout << endl;
    }
    system("pause");
}



4.10 數字啞謎和迴文

#include<iostream>
#include<string>
using namespace std;
// 題目:人過大佛寺*我=寺佛大過人.   其中每個字母代表着一個不同的數字.
int main()
{
	bool flag;
	bool IsUsed[10];
	int number,revert_number,t,v;
	for(number=0;number<100000;number++)
	{
		flag=true;
		memset(IsUsed,0,sizeof(IsUsed));
		t=number;
		revert_number=0;
		for(int i=0;i<5;i++)
		{
			v=t%10;
			revert_number=revert_number*10+v;
			t/=10;
			if(IsUsed[v])
				flag=false;
			else
				IsUsed[v]=1;
		}
		if(flag&&(revert_number%number==0))
		{
			v=revert_number/number;
			if(v<10&&!IsUsed[v])
				cout<<number<<" "<<v<<" "<<revert_number<<endl;
		}
	}
	system("pause");
	return 0;
}

編程之美 完

以上有些代碼參考《編程之美》還有一些是參考網絡上的,剩下的是自己編寫的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章