算法竞赛入门经典-第五章源代码

// 程序5_1_1 WERTYU
#include <stdio.h>
const char* s = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./"; //常量数组
int main(void)
{
    int i, c;
    while((c=getchar()) != EOF){
        for(i=1; s[i]&&s[i]!=c; i++); //找 // 注意最后的'\0'
        if(s[i]) putchar(s[i-1]);
        else putchar(c);	// 未找到则原样输出
    }
    return 0;
}

// 程序5_1_2 TeX括号
#include <stdio.h>
int main(void)
{
    int c, q = 1; //如何判断左引号还是右引号?使用一个标志变量
    while((c=getchar()) != EOF){
        if(c == '"'){
            printf("%s", q ? "“":"”");
            q = !q;
        }
        else
            printf("%c", c);
    }
    return 0;
}

// 程序5_1_3 周期串
#include <stdio.h>
#include <string.h>
int main(void)
{
    char word[100];
    scanf("%s", word);
    int len = strlen(word);
    for(int i=1; i<=len; i++)// 从小到大枚举各个周期
    	if(len%i == 0) // 周期必须为整数倍
     	{
         	int ok = 1;
         	for(int j=i; j<len; j++)
          		if(word[j] != word[j%i]) // “对应”验证
          		{    // “周期”总跟“取余”有关
              		ok = 0; // 全部与第一对比较
              		break;
          		}
         	if(ok)
         	{
             	printf("%d\n", i);
             	break;
         	}
     	}
    return 0;
}

// 程序5_2_1 小学生算术
#include <stdio.h>
int main(void)
{
    int a, b;
    while(scanf("%d%d", &a, &b)==2){
        if(!a && !b) return 0;
        int c = 0, ans = 0;
        for(int i=0; i<10; i++){	// 最多处理十次,注意整型上限
            c = (a%10+b%10+c)>9 ? 1:0;// 一次最多进一位
            ans += c;	 // 分离出个位
            a /= 10;
            b /= 10;
        }
        printf("%d\n", ans);
    }
    return 0;
}

// 程序5_2_2 阶乘的精确值
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAXN 10000
int f[MAXN];
int main(void)
{
    int i, j, n, c, s;
    scanf("%d", &n);
    memset(f, 0, sizeof(f));
    f[0] = 1;
    for(i = 2; i <= n; i++){
        c = 0;
        for(j = 0; j < MAXN; j++){
            s = f[j] * i + c;
            f[j] = s % 10;
            c = s / 10;
        }
    }
    for(j=MAXN-1; j>=0; j--) if(f[j]) break;
    for(i=j; i>=0; i--) printf("%d", f[i]);
    printf("\n");
    printf("%f\n", (double)clock()/CLOCKS_PER_SEC);
    return 0;
}

// 程序5_2_3 高精度运算类bign
// 程序5_2_4 重载bign的常用运算符
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1000;

struct bign
{
	int len;
	int s[MAXN];
	bign()
	{
	 	memset(s, 0, sizeof(s));
	 	len = 1;
	}
	bign(int num)
	{
	 	*this = num;
	}
	bign(const char* num)
	{
	 	*this = num;
	}
	bign operator=(const char* num)
	{
  		len = strlen(num);	// 字符串转化为“逆序数组+长度”的内部表示方法
  		for(int i=0; i<len; i++)
   		s[i] = num[len-i-1] - '0';
  		return *this;	// 可以连续赋值
 	}
	bign operator=(int num)
	{
	 	char s[MAXN];
	 	sprintf(s, "%d", num);	// 先转化为字符串
	 	*this = s;	 // 再调用字符串赋值函数
	 	return *this;
	}
	string str() const	// 表明x.str()不会改变x
	{
	 	string res = "";
	 	for(int i=0; i<len; i++)	// 转化为字符串
	  		res = (char)(s[i]+'0') + res;
	 	if(res == "")
	  		res = "0";
	 	return res;
	}
	bign operator+(const bign& b) const
	{
	 	bign c;
	 	c.len = 0;
	 	for(int i=0, g=0; g||i<max(len,b.len); i++)
	 	{
	  		int x = g;
	  		if(i < len) x += s[i];
   			if(i < b.len) x += b.s[i];
   			c.s[c.len++] = x % 10;
   			g = x / 10;
  		}
  		return c;
 	}
	bign operator+=(const bign& b)
	{
	 	*this = *this + b;
	 	return *this;
	}
	bool operator<(const bign& b) const
	{
	 	if(len != b.len) return len < b.len;
	 	for(int i=len-1; i>=0; i--)
	  		if(s[i] != b.s[i])
	   			return s[i] < b.s[i];
	 	return false;
	}
	bool operator>(const bign& b) const
	{
	 	return b < *this;
	}
	bool operator<=(const bign& b) const
	{
	 	return !(b < *this);
	}
	bool operator>=(const bign& b) const
	{
	 	return !(*this < b);
	}
	bool operator!=(const bign& b) const
	{
	 	return b<*this || *this<b;
	}
	bool operator==(const bign& b) const
	{
	 	return !(b<*this) && !(*this<b);
	}
};

// 让输入输出流直接支持bign结构体
istream& operator>>(istream& in, bign& x)
{
 	string s;
 	in >> s;
 	x = s.c_str();
 	return in;
}

ostream& operator<<(ostream& out, const bign& x)
{
 	out << x.str();
 	return out;
}

int main(void)
{

    return 0;
}

// 程序5_3_1 6174问题
#include <stdio.h>
#include <string.h>
int num[2000], count;
int get_next(int x)
{
	int a, b, n;
	char s[10];
	sprintf(s, "%d", x);
	n = strlen(s);
	for(int i=0; i<n; i++)
	 	for(int j=i+1; j<n; j++)
	  		if(s[i] > s[j])
	  		{
	  		 	char t = s[i];
	   			s[i] = s[j];
	   			s[j] = t;
	  		}
	sscanf(s, "%d", &b);
	for(int i=0; i<n/2; i++)
	{
	 	char t = s[i];
	 	s[i] = s[n-1-i];
	 	s[n-1-i] = t;
	}
	sscanf(s, "%d", &a);
	return a - b;
}
int main(void)
{
	scanf("%d", &num[0]);
	printf("%d\n", num[0]);
	count = 1;
	while(1)
	{
	 	num[count] = get_next(num[count-1]);
	 	printf(" -> %d\n", num[count]);
	 	int found = 0;
	 	for(int i=0; i<count; i++)
	  		if(num[i] == num[count])
	  		{
	   			found = 1;
	   			break;
	  		}
	 	if(found) break;
	 	count++;
	}
	printf("\n");
	return 0;
}

// 程序5_3_2 字母重排
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int n;
char word[2000][10], sorted[2000][10];
int cmp_char(const void* _a, const void* _b)
{
 	char* a = (char*)_a;
 	char* b = (char*)_b;
 	return *a-*b;
}
int cmp_string(const void* _a, const void* _b)
{
 	char* a = (char*)_a;
 	char* b = (char*)_b;
 	return strcmp(a, b);
}
int main(void)
{
 	n = 0;
 	while(1)
 	{
  		scanf("%s", word[n]);
  		if(word[n][0] == '*') break;
  		n++;
 	}
 	qsort(word, n, sizeof(word[0]), cmp_string);
 	for(int i=0; i<n; i++)
 	{
  		strcpy(sorted[i], word[i]);
  		qsort(sorted[i], strlen(sorted[i]), sizeof(char), cmp_char);
 	}
 	char s[10];
 	while(scanf("%s", s) == 1)
 	{
  		qsort(s, strlen(s), sizeof(char), cmp_char);
  		int found = 0;
  		for(int i=0; i<n; i++)
   			if(strcmp(sorted[i], s) == 0)
   			{
    			found = 1;
    			printf("%s ", word[i]);
   			}
  		if(!found) printf(":(");
  		printf("\n");
 	}
 	return 0;
}

// 程序5_4_1 Cantor的数表
#include <stdio.h>
#include <math.h>
int main(void)
{
 	int n;
 	while(scanf("%d", &n) != EOF)
 	{
 	 	int k = (int)ceil((sqrt(1+8*n)-1)/2);	// 通过代数运算得出
 	 	//int k = (int)floor((sqrt(8.0*n+1)-1)/2-1e-9)+1;
 	 	int s = k*(k+1)/2;
 	 	printf("%d/%d\n", s-n+1, k-s+n);	// 从特殊中找规律
 	}
 	return 0;
}

// 程序5_4_2 因子和阶乘
#include <stdio.h>
#include <string.h>
int is_prime(int n)
{
 	for(int i=2; i*i<=n; i++)
  		if(n%i == 0) return 0;
 	return 1;
}
int prime[100], count=0;
int main(void)
{
 	int n, p[100];	// “双排”数组,对应记录指数
 	for(int i=2; i<=100; i++)	// 构造素数表
  		if(is_prime(i)) prime[count++]=i;
 	while(scanf("%d", &n) != EOF)
 	{
  		printf("%d! =", n);
  		memset(p, 0, sizeof(p));
  		int maxp = 0;
  		for(int i=1; i<=n; i++)	 // 注意是阶乘,需逐个处理
  		{
   			int m = i;	// 为了不改变i的值
   			for(int j=0; j<count; j++)
    			while(m%prime[j] == 0)
    			{
     				m /= prime[j];
     				p[j]++;
     				if(j > maxp) maxp = j;
    			}
  		}
  		for(int i=0; i<=maxp; i++)
   			printf(" %d", p[i]);
  		printf("\n");
 	}
 	return 0;
}

// 程序5_4_3 果园里的树
#include <stdio.h>
#include <math.h>
double area(double x0, double y0, double x1, double y1, double x2, double y2)
{
 	return fabs((x0*y1+x2*y0+x1*y2-x2*y1-x0*y2-x1*y0)/2);
}
int main(void)
{
	double x0,y0,x1,y1,x2,y2;
	double s, s1, s2, s3;
	int cnt;
	while(scanf("%lf%lf%lf%lf%lf%lf", &x0, &y0, &x1, &y1, &x2, &y2) != EOF)
	{
	 	cnt = 0;
	 	s = area(x0, y0, x1, y1, x2, y2);
	 	for(int i=1; i<100; i++)
	  		for(int j=1; j<100; j++)
	  		{
	   			s1 = area(i, j, x1, y1, x2, y2);
	   			s2 = area(x0, y0, i, j, x2, y2);
	   			s3 = area(x0, y0, x1, y1, i, j);
	   			if(fabs(s-s1-s2-s3) < 1e-5) cnt++;
	  		}
	 	printf("%d\n", cnt);
	}
	return 0;
}

// 程序5_4_4 多少块土地 ??

转载于:https://www.cnblogs.com/yanweicode/p/4356293.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值