算法入门
最近一直在学习算法,因此看了算法竞赛入门经典这本书,因此把这本书的很多习题和讲解都自己做了一下,感觉对自己帮助非常大,由于工作量非常大,并不是几天就能写完的,所以我打算每天都花一些时间来写写上面的代码,并且把自己所写的记录下来,本部分内容会持续更新。。。
今天所做的一些题如下,对大家应该非常有帮助吧!
蛇形填数
在nxn方阵里填入1,2,……,nxn,要求填成蛇形。例如,n=4时方阵为
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
之前在一次校园招聘中遇到了蛇形填数这道题,当时由于时间很紧,就写了一些,现在重新做到这道题,理解相当深刻了。以后遇到这类题的时候,只要套用这个模板就可以做出来了。
#include <stdio.h>
#include <iostream>
using namespace std;
#define maxn 20
int a[maxn][maxn];
int main(){
int n, x, y, tot = 0;
scanf("%d", &n);
memset(a, 0, sizeof(a));
tot = a[x = 0][y = n - 1] = 1;
while (tot<n*n)
{
while (x + 1 < n && !a[x + 1][y]) a[++x][y] = ++tot;
while (y - 1 >= 0 && !a[x][y-1]) a[x][--y] = ++tot;
while (x - 1 >= 0 && !a[x-1][y]) a[--x][y] = ++tot;
while (y + 1 < n && !a[x][y+1]) a[x][++y] = ++tot;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++){
printf("%3d", a[i][j]);
}
printf("\n");
}
system("pause");
return 0;
}
Tex中的引号
在Tex中,左引号是”",右引号是“‘’”。输入一篇包含双引号的文章,任务是把它转换成Tex的格式
to be or not to be’
样例输入:
“ to be or not to be”
输出:
我们有时候会遇到这类题,对字符串的处理,本例值得参考
#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
int c, q = 1;
while ((c = getchar())!=EOF) //读取字符
{
if (c == '"')
{
printf("%s", q ? "``" : "''");
q = !q; //控制输出`` 还是''
}
else
{
printf("%c", c);
}
}
system("pause");
return 0;
}
把手放在键盘上,稍不注意就会往右错一位。这样,输入Q会变成W,输入J会变成输入K等。输入一个错位后敲出的字符串(所有字母均大写),输出打字员想打出的句子。输入保证合法,一定是错位之后的字符串。例如输入中不会出现大写字母A。
样例输入:O S, GOMR YPFSU/
输出:I AM FINE TODAY.
#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'\ZXCVBNM,./"; //字符串保存键盘上的大写字母
int c;
int i;
while ((c =getchar())!=EOF)
{
for (i = 1; i < strlen(s); i++){ //遍历寻找
if (s[i]==c)
{
break; //找到退出循环
}
}
if (s[i])
{
printf("%c", s[i - 1]);
}
else
printf("%c", c);
}
system("pause");
return 0;
}
回文串
输入一个字符串,判断它是否为回文串,例如abba
回文串是在公司笔试题中经常遇到的问题,我在这里简单的写了一个例子,虽然简单,但是应该帮助挺大。
#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
char s[30];
while (scanf("%s",s)==1)
{
int len = strlen(s);
int mid = (len + 1) / 2;
int p=1;
for (int i = 0; i < len; i++)
{
if (s[i] != s[len - 1 - i])
p = 0;
}
if (p) printf("a regular palindreome");
else
printf("not a alindrome");
}
system("pause");
return 0;
}
猜数字游戏的提示
实现一个经典”猜数字”游戏。给定答案序列和用户猜的序列,统计有多少数字位置正确 (A),有多少数字在两个序列都出现过但位置不对(B)。
输入包含多组数据。每组输入第一行为序列长度n,第二行是答案序列,接下来是若干 猜测序列。猜测序列全0时该组数据结束。n=0时输入结束。
#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
const int maxn = 1020;
int a[maxn],b[maxn],n;
int kcase = 0;
while (scanf("%d",&n)==1 && n) //输入数字数目,当为0时结束游戏
{
printf("Game %d\n", ++kcase);
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]); //输入答案序列
}
for (;;)
{
int A = 0;
int B = 0;
for (int i = 0; i < n; i++){
scanf("%d", &b[i]); //输入猜测序列
if (a[i] == b[i])
{
A++; //正确位置
}
}
if (b[0] == 0)
{
break;
break; //当猜测序列第一个为0时,退出游戏
}
for (int d = 1; d < 9; d++)
{
int c1 = 0, c2 = 0;
for (int i = 0; i < n; i++)
{
if (a[i] == d)
{
c1++;
}
if (b[i] == d)
{
c2++;
}
}
if (c1 < c2)
{
B += c1;
}
else
B += c2;
}
printf("(%d,%d)\n", A, B - A);
}
}
system("pause");
return 0;
}
环状序列
长度为n的环状串有n种表示法,分别为从某 个位置开始顺时针得到。例如,下图的环状串 有10种表示:
CGAGTCAGCT,GAGTCAGCTC,AGTCAGCTCG等。在这些表示法中,字典序最小的称 为”最小表示”。
#include <stdio.h>
#include <iostream>
using namespace std;
int compare(const char *s, int p, int q);
int main(){
const int maxn = 1024;
char s[maxn];
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%s", s);
int ans = 0; //最终得到的位置
int len = strlen(s);
for (int j = 0; j < len; j++)
{
if (compare(s, j, ans)) ans = j;
}
for (int m = 0; m < len; m++)
{
putchar(s[(ans + m) % len]);
}
}
system("pause");
return 0;
}
int compare(const char *s, int p, int q){ //比较字符串p和q位置起的字典排序
int n = strlen(s);
for (int i = 0; i < n; i++)
{
if (s[(p + i) % n] != s[(q + i) % n])
return s[(p + i) % n] < s[(q + i) % n];
}
return 0;
}
好了,本篇文章写了几个小程序,读者遇到类似问题都可以直接copy代码在vs中运行,作为一名刚开始写博客的小白来说,水平一般,望大家谅解,我会继续努力的,敬请期待。