文章内容主要参考刘汝佳著作《算法竞赛入门经典》(第2版)
memcpy用法
头文件:cstring
用法:
memcpy(b,a,sizeof(int)*k);
这是a,b都是整型数组的时候,把a数组中的前k个元素赋值给b
memcpy(b,a,sizeof(a));
把a中所有的元素赋值给b
开灯问题—注意不要输出多余的空格
参考《算法竞赛入门经典》(第2版)
题目:有n盏灯,编号为1~n,第1个人把所有灯打开,第2个人按下所有编号为2的倍数的开关(这些灯将被关掉),第3个人按下所有编号为3的倍数的开关(其中关掉的灯被打开, 开着灯将被关闭),依此类推。一共有k个人,问最后有哪些灯开着?输入:n和k,输出开着的灯编号。k≤n≤1000。
样例输入:
7 3
样例输出:
1 5 6 7
《算法竞赛入门经典》(第2版)39页代码参考改写如下:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
bool a[1005];
int n,k;
int first=1;
memset(a,false,sizeof(a));
cin>>n>>k;
for(int i=1;i<=k;i++)
for(int j=1;j<=n;j++)
if(j%i==0)
a[j]=!a[j];
for(int i=1;i<=n;i++)
{
if(a[i]==1)
{
if(first)first=0;
else
cout<<" ";
cout<<i;
}
}
cout<<endl;
return 0;
}
蛇形填数
参考《算法竞赛入门经典》(第2版)
在nxn的方阵中填入1,2,…,nxn,要求填成蛇形。例如,n=4时方阵是:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
int a[20][20];
int n;
while(cin>>n)
{
memset(a,0,sizeof(a));
int x,y;
int tmp=a[x=0][y=n-1]=1;
while(tmp<n*n)
{
while(x<n-1 && !a[x+1][y]) a[++x][y]=++tmp;
while(y>0 && !a[x][y-1]) a[x][--y]=++tmp;
while(x>0 && !a[x-1][y]) a[--x][y]=++tmp;
while(y<n-1 && !a[x][y+1]) a[x][++y]=++tmp;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(j==0)printf("%-3d",a[i][j]);
else printf(" %-3d",a[i][j]);
}
cout<<endl;
}
}
return 0;
}
竖式问题—补充字符串处理函数strchr、strstr、strrev、sprintf)
参考《算法竞赛入门经典》(第2版)
问题描述:
找出形如 abc*de (三位数乘以两位数) 的算式,使得在完整的竖式中,所有数字属于一个特定的数字集合。输入数字集合 (相邻数字之间没有空格),输出所有竖式。每个竖式前应有编号,之后应有一个空行。最后输出解的总数。(在样例中,为了便于观察,竖式中的空格用小数点代替,但所写的程序中应该输出空格)
样例输入:
2357
样例输出:
<1>
..775
X..33
.2325
2325.
25575
The number of solutions=1
参考代码:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char s[15],buf[50];
int kase=0;
cin>>s;
for(int abc=111;abc<=999;abc++)
{
for(int de=11;de<=99;de++)
{
int x=abc*(de%10),y=abc*(de/10),z=abc*de;
sprintf(buf,"%d%d%d%d%d",abc,de,x,y,z);
bool flag=1;
for(int i=0;i<strlen(buf);i++)
if(strchr(s,buf[i])==NULL) flag=0;
if(flag)
{
cout<<"<"<<++kase<<">"<<endl;
printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n",abc,de,x,y,z);
}
}
}
cout<<"The number of solutions = "<<kase<<endl;
return 0;
}
- 关于strchr函数:
函数原型:extern char *strchr(char *str,char character)
参数说明:str为一个字符串的指针,character为一个待查找字符。
所在库名:cstring
函数功能:从字符串str中寻找字符character第一次出现的位置。
返回说明:返回指向第一次出现字符character位置的指针,如果没找到则返回NULL。
- 关于strstr函数
原型:char *strstr(const char *str1, const char *str2);
所在库名:cstring
找出str2字符串在str1字符串中第一次出现的位置(不包括str2的串结束符)。返回该位置的指针,如找不到,返回空指针。
- 关于strrev函数
函数原型:extern char *strrev(char *str)
参数说明:str为源字符串,即待逆置的字符串。
所在库名:cstring
函数功能:实现字符串str的逆置。
返回说明:返回逆置字符串的指针。
代码示范:
#include<cstdio>
#include<cstring>
int main()
{
char s[10]="abcd";
char *p=strrev(s);
printf("%p\n",p);
printf("%s\n",s);
return 0;
}
子串 OpenJ_Bailian - 2744
现在有一些由英文字符组成的大小写敏感的字符串,你的任务是找到一个最长的字符串x,使得对于已经给出的字符串中的任意一个y,x或者是y的子串,或者x中的字符反序之后得到的新字符串是y的子串。
Input
输入的第一行是一个整数t (1 <= t <= 10),t表示测试数据的数目。对于每一组测试数据,第一行是一个整数n (1 <= n <= 100),表示已经给出n个字符串。接下来n行,每行给出一个长度在1和100之间的字符串。
Output
对于每一组测试数据,输出一行,给出题目中要求的字符串x的长度。
Sample Input
2
3
ABCD
BCDFF
BRCD
2
rose
orchid
Sample Output
2
2
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=105;
int n;
char s[maxn][maxn];
void sstrrev(char s[])
{
int len=strlen(s);
for(int i=0;i<=(len-1)/2;i++)
swap(s[i],s[len-1-i]);
}
bool solve(char s[maxn][maxn],char ss[])
{
char sss[maxn];
strcpy(sss,ss);
sss[strlen(ss)]='\0';
sstrrev(sss);
sss[strlen(ss)]='\0';
for(int i=0;i<n;i++)
if(strstr(s[i],ss)==NULL && strstr(s[i],sss)==NULL)
return false;
return true;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int mmax=0;
cin>>n;
int min_len=maxn,mark;
for(int i=0;i<n;i++)
{
cin>>s[i];
if(min_len>strlen(s[i]))
{
min_len=strlen(s[i]);
mark=i;
}
}
for(int i=0;i<min_len;i++)
{
int cnt=0;
for(int j=i;j<min_len;j++)
{
char s1[maxn];
strncpy(s1,s[mark]+i,j-i+1);
s1[j-i+1]='\0';
if(solve(s,s1))
{
cnt++;
}
else
break;
}
mmax=max(mmax,cnt);
}
cout<<mmax<<endl;
}
return 0;
}