#include <stdio.h> #include <time.h> #include <string.h> #include <math.h> #include <algorithm> #include <iostream> using namespace std; const int N=1000010; void text(); int main() { freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); text(); printf("%lf\n",clock()/(double)CLOCKS_PER_SEC); return 0; }
/* //5.1.3周期串 void text(){ char f[101];int flag; scanf("%s",f);int i,j,len=strlen(f); for(i=1;i<len;i++){ if(len%i==0){ flag=1; for(j=i+1;j<len;j++) if(f[j%i]==f[j]) continue; else{ flag=0;break; } } if(flag) break; } printf("%d\n",i); } */ /* //5.2.1小学生算术 void text(){ int i,a,b; scanf("%d %d",&a,&b); int c=0,ans=0; for(i=0;i<9;i++){ c= (a%10+b%10+c)>9 ? 1 : 0; ans += c; a/=10; b/=10; } printf("%d\n",ans); } */ /* //5.2.2阶乘的精确值(大数阶乘) void text(){ int f[1010];memset(f,0,sizeof(f)); int i,j,n; f[0]=1;int s,c; scanf("%d",&n); for(i=2;i<=n;i++){ c=0; for(j=0;j<1010;j++){ s=f[j]*i+c; c=s/10; f[j]=s%10; } } //先去除前导0; for(j=1009;j>=0;j--) if(f[j]) break; for(i=j;i>=0;i--) printf("%d",f[i]); printf("\n"); } */ /* // int get_next(int x){ char s[10]; int a,b,n; sprintf(s,"%d",x); //转化为字符串; n=strlen(s); for(i=0;i<n;i++) for(j=1;j<n;j++) if(f[i]>f[j]){ char t=f[i];f[i]=f[j];f[j]=t; } //给数字冒泡排序; sscanf(s,"%d",&b);//将字符串s赋值给数字b。---小数 //字符反转 for(i=0;i<n/2;i++){ char q; q=f[i];f[i]=f[n-1-i];f[n-1-i]=q; } sscanf(s,"%d",&a);//重排后的大数。 return a-b; } */

/* //5.4.3果园里的树:判断点是否在三角形内---利用三角形的有向面积。(线性代数矩阵) double area(double x0,double y0,double x1,double y1,double x2,double y2){ return x0*y1+x2*y0+x1*y2-x2*y1-x0*y2-x1*y0; } void text(){ int i,j,k; double x0,y0,x1,y1,xd2,y2; double a,b;//枚举当前点---二维 while(scanf("%lf %lf %lf %lf %lf %lf",&x0,y0,x1,y1,x2,y2)!=EOF){ int num=0; for(a=1;a<100;a++) for(b=1;b<100;b++){ //if() //判断面积是否相同即可! } } } */ /* //6.1.1卡片游戏:STL队列的应用; queue <int> s;//声明一个队列s。 /* STL中队列的常用"函数": q.push(x); 队尾加入元素x; q.pop(); 队列删除队头元素; q.empty(); 空则返回1,否则返回0; q.front(); 打印队首元素。 #include <queue> void text(){ int i,j,k,n;int f[101]; while(scanf("%d",&n) && n){ queue <int> q; for(i=0;i<n;i++) q.push(i+1); //队尾加入元素。 while(!q.empty()){ printf("%d ",q.front()); q.pop(); q.push(q.front()); q.pop(); }printf("\n打印完毕!所有元素出队。\n"); } } */ /* //6.1.2铁轨:STL中栈的使用;stack <int> q; //声明一个栈; STL中栈的常用"函数": q.empty(); 队列是否为空,空则返回1; q.top(); 栈顶元素; q.pop(); 栈顶退栈; q.push(x); 栈顶进栈! #include <stack> void text(){ int f[101]; int i,j,k,n; while(scanf("%d",&n) && n){ for(i=1;i<=n;i++) scanf("%d",&f[i]); stack <int> q; int a=1,b=1,ok=1; while(b<=n){ if(a==f[b]){a++; b++;} else if(!q.empty() && q.top()==f[b]){ q.pop();b++; } else if(a<=n) q.push(a++); else{ ok=0;break; } }printf("%s\n", ok ? "yes" : "no"); } } */ /* //读取带空格字符串的实验: fgets(); void text(){ char f[101]; while(fgets(f,sizeof(f),stdin)!=NULL){ printf("%s",f); //注意这里,回车也自动读入了!! } } */
第六章: 数据结构

/* //6.3.1小球下落 const int DD=20; int f[1<<DD]; void text(){ //小球下落。 int i,j,I;int D; while(scanf("%d %d",&D,&I) && I){ memset(f,0,sizeof(f));int n=(1<<D)-1;int k; for(i=1;i<=I;i++){//连续让I个小球下落。 k=1;//每次都从第一个小球开始下落。 while(1){ f[k] = !f[k] ; k = f[k] ? 2*k : 2*k+1 ; if(k>n) break; } }//这里注意一下k的范围! 当在for循环内又重定义时,会 //仅在{}内有用,而到{}外之后,会重新使用main()中定义的k!! printf("%d\n",k/2); } } //技巧: <<的使用: 1<<n = 1^n ; // f[k] = !f[k];---> 取反操作。 */ /* //6.3.2层次遍历(树)---->使用一下队列 queue ! #include <queue> typedef struct LNode{ int v;int value; LNode *l,*r; }LNode,*LinkList;//定义树节点类型。 LinkList root;int failed; void Add(int v,char *s){ //插入节点的操作。 LinkList p=root;//从根节点开始往下走; int flag=0,n=strlen(s)-1,i; for(i=0;i<n;i++){ if(s[i]=='L'){ if(p->l==NULL){ LinkList a=new LNode(); a->l=a->r=NULL; a->value=0; p->l=a;p=p->l; } else p=p->l; } else if(s[i]=='R'){ if(p->r==NULL){ LinkList a=new LNode(); a->l=a->r=NULL; a->value=0; p->r=a; p=p->r; } else p=p->r; } } if(p->value) failed=1; p->v=v;p->value=1; } void Creat(){ char f[22];int v; while(scanf("%s",f)==1){ if(f[1]==')') break; sscanf(&f[1],"%d",&v); Add(v,strchr(f,',')+1); } printf("创建二叉树完毕!\n"); } void Print(LinkList p){ if(p){ printf("%d ",p->v); Print(p->l); Print(p->r); } } void Print1(LinkList p){ int i,j,front=0,last=0; LinkList s[50],q; s[last++]=p; while(front<last){ q=s[front++]; printf("%d ",q->v); if(q->l) s[last++]=q->l; if(q->r) s[last++]=q->r; } printf("\n层次遍历完毕!\n"); } //补充一下 sscanf() 与 sprintf() 的用法 以及 strchr()的用法 。 /* 1. sscanf: sscanf(&f[0],"%d",&x); 将字符串f的从0位开始的一个数字,写入到int x中; sprintf: sprintf(&f[0],"%d",x); 将数字x转化为字符串,从0位开始存。 注意: 第一位参数都是地址! 2. strchr(&f[0],'b') : 从0位开始(包括0位)向后第一位b的地址! 如果结果减去f,可以转化为第几位! void text(){ root=new LNode();//创建根节点; root->r=root->l=NULL;root->v=-1;root->value=0; failed=0; Creat(); if(failed) printf("-1\n"); else{ int i,j,k; Print(root);printf("\n"); //下面写层次遍历。 Print1(root); } } */
图:

/* //6.4.1黑白图像(图的深搜 dfs) int f[101][101],vis[101][101];int num; void dfs(int i,int j){ if(vis[i][j]==0 && f[i][j]){ vis[i][j]=1; num++; dfs(i-1,j);dfs(i+1,j); dfs(i,j-1);dfs(i,j+1); } } void text(){ int i,j,k;char str[101]; int n,m; while(scanf("%d %d",&n,&m)!=EOF){ memset(f,0,sizeof(f));memset(vis,0,sizeof(vis));//初始化 for(i=0;i<n;i++){ scanf("%s",str);int len=strlen(str); for(j=0;j<len;j++) f[i+1][j+1]=str[j]-'0'; }//输入相关图信息; int count=0;int max=-1; for(i=1;i<=n;i++) for(j=1;j<=m;j++){ num=0; if(vis[i][j]==0 && f[i][j]){ count++;dfs(i,j); if(num>max) max=num; } } printf("共有 %d 个黑色连块, 最大连块为 %d 块。\n",count,max); }//黑色为1,白色为0; } */ /* //6.4.2走迷宫(图的广搜 bfs ) int f[10][10],vis[10][10]; int fa[10][10];//定义每个当前节点的父节点 int dist[10][10];//记录起始点到当前节点的最短距离。 int dir[10][10];//定义其父节点向当前节点的行走方向。 int dx[5]={-1,1,0,0},dy[5]={0,0,-1,1}; void Print(int x,int y,int m){ //打印路径; 从末尾开始反向进行查找路径; //这里设定末尾为 0,,m-1; int path[100];int i,j;i=0;int u=x*m+y; while(u!=0){ path[i++]=x*m+y; u=fa[x][y]; x=u/m;y=u%m; } for(j=i-1;j>=0;j--) printf("%d ",path[j]); } void text(){ int i,j,k,n,m; while(scanf("%d %d",&n,&m)!=EOF){ memset(f,0,sizeof(f)); memset(vis,0,sizeof(vis)); for(i=0;i<n;i++) for(j=0;j<m;j++) scanf("%d",&f[i][j]); //图的 bfs, 广度优先遍历-------都需要用到队列! int q[101];memset(q,0,sizeof(q));//定义一个队列; int x,y,front,rear;front=rear=0;x=y=0; q[0]=0;rear=1; vis[0][0]=1;fa[x][y]=0;dist[x][y]=0; //这里别忘初始化!! int xx,yy;int u; while(front<rear){ u=q[front++]; x=u/m;y=u%m; //当前节点的数值排列转化为坐标; for(i=0;i<4;i++){ xx=x+dx[i];yy=y+dy[i];//上下左右、按顺序的坐标 if(xx>=0 && yy>=0 && xx<n && yy<m && !vis[xx][yy] && f[xx][yy]==0){ //满足条件; int uu=xx*m+yy; //第uu个节点; fa[xx][yy]=u; dir[xx][yy]=i;//父节点向其过来的方向。 q[rear++]=uu;//进队。 vis[xx][yy]=1; dist[xx][yy]=dist[x][y]+1;//长度加一; } } } Print(0,m-1,m);//假设末尾节点在 (0,m-1) 处; for(i=0;i<n;i++){ for(j=0;j<m;j++) printf("%02d ",fa[i][j]); printf("\n"); } } } //注意点: 遍历之前的初始化 && 进队列一位数之后,需要进行初步vis,fa数组的处理! */