一些小题目

以前的那篇文章写得太长了,重开一篇

 

1,平面分割问题

 

设有n条封闭曲线画在平面上,任何两条封闭曲线恰好相交于两点,任何三条封闭曲线不相交于同一点,问这些封闭曲线把平面分割成的区域个数。

 

实际上。第n个曲线增加了平面的区域个数为2(n-1)

A(n)=A(n-1)+2(n-1),当n=1时,A(1)=2

代码简单的递推或者递归都可以实现

 

2, 区间染色问题

 

给出n个区间,已知对于[t0,t1]的任一点,都至少被一个区间所覆盖,要求对其中若干个区间进行染色,是的仅被一个染色区间覆盖的区域长度不少于2/3*(t1-t0).

 

a,首先对染色区间做处理,去掉一个区间被其他区间覆盖的情况

如下这种

------------

   ---------------

     ----------------

其中的第二行被第一行和第三行覆盖,去掉第二行的这个区间

则,剩余的区间为以下的这种情况

x---------    y-----------

       z-----------

统计奇数区间长度L1=(b1-a1)+(b3-a3),偶数区间长度L2,以及奇偶长度(不被其他覆盖的区域)L3=a2-a1+(a3-b1+a4-b2+..+)+b[n]-b[n-1]

 

只需证明若L1,L2<2/3*(t1-t0),则必有L3>=2/3*(t1-t0) 即可

 

证明很简单,省略了

代码如下

#include <iostream> void segmentColorProblem(int n,int t0,int t1) { int l1=0,l2=0,l3=0; int *a=new int[n+1]; int *b=new int[n+1]; double s=2/3*(t1-t0); for(int i=1;i<n;i++) { std::cin>>a[i]>>b[i]; } l3=2*(b[n]-a[1]); for(int i=1;i<=n;i++) { if(i%2==1) { l1+=b[i]-a[i]; } else if(i%2==0) { l2+=b[i]-a[i]; } l3+=a[i]-b[i]; } if(l1>=s) std::cout<<"l1 is the answer"<<std::endl; else if(l2>=s) std::cout<<"l2 is the answer"<<std::endl; else std::cout<<"l3 is the answer"<<std::endl; return; } 

3, 论文改烦了,做了一道简单的题目消遣了一下。花了25分钟。。。。。。。。。。。。。。。。。。。。。挺简单的,就不写分析了

 

有道2009复赛第一题
Problem Statement:

如果一个数字十进制表达时,不存在连续两位数字相等,则称之为“不重复数”。例如,105,1234和12121都是“不重复数”,而11,100和1225不算。给定一个long类型数字A,返回大于A的最小“不重复数”。

Definition:

Class: UnrepeatingNumbers 
Method: next 
Parameters: long 
Returns: long 
Method signature: long next(long A)
(be sure your method is public) 

Constraints:

A 取值范围是[0, 10^17],注意是闭区间。

 

 

Examples:
0) 54
  returns: 56
  大于54的最小数字是55,但55不是“不重复数”。下一个数字是56,它满足条件。

 

1) 10
  returns: 12

 

2) 9
  returns: 10

 

3) 98
  returns: 101
  99和100都不是“不重复数”, 101是。

 

4) 21099
  returns: 21201

 

#include "stdafx.h" #include <iostream> #include <string> int connNum() { int num[17]; for(int i=0;i<17;i++) { num[i]=0; } std::string temp; std::cin>>temp; int len=temp.length(); for(int i=0;i<len;i++) { num[len-i-1]=temp[i]-'0'; } int j=len-2; while(j>=0&&num[j]!=num[j+1]) { j--; } if(j<0) j=0; while(j>=0) { num[j]++; int tempIndex=j; while(tempIndex>=1) { num[tempIndex-1]=0; tempIndex--; } int plusToPre=num[j]/10; num[j]=num[j]%10; tempIndex=j+1; while(plusToPre!=0) { num[tempIndex]+=plusToPre; plusToPre=num[tempIndex]/10; num[tempIndex]=num[tempIndex]%10; tempIndex++; } if(tempIndex>=len) len=tempIndex; j=len-2; while(j>=0&&num[j]!=num[j+1]) { j--; } } for(int i=len-1;i>=0;i--) { std::cout<<num[i]; } return 1; } int main() { connNum(); system("pause"); return 0; }  

4,有2^n个选手参加比赛。一直有两个选手比赛的时候总是强的一方获胜。且不会出现某两个选手一样强的情况。每个选手每天至多同一个对手比赛。试给出一种赛程的安排,使得在n*(n+1)/2天内确定所有选手的强弱。。

 

分析:对这个题目,由题目中所描述的,所有的选手强弱必然有个顺序,所以

就不会存在a>b>c>a这种圈存在

这种强弱关系是单链式的。

#include "stdafx.h" #include <iostream> struct p { int id; p* next; }; int g[1024][1024]; class raceTwo { p * r; int n;//the number of athlete int total; public: raceTwo() { total=0; r=new p; r->id=0; p * head=new p; head->id=1; head->next=NULL; r->next=head; std::cin>>n; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { std::cin>>g[i][j]; } } for(int i=2;i<=n;i++) { bool notEnd=true; p * tempNode=r; while(notEnd) { if(tempNode->next==NULL) { p * t=new p; t->id=i;t->next=NULL; tempNode->next=t; notEnd=false; } else { p * curr=tempNode->next; total++; std::cout<<i<<"vs"<<curr->id<<std::endl; if(g[i][curr->id]>0) { tempNode=tempNode->next; } else { p * t=new p; t->id=i;t->next=curr; tempNode->next=t; notEnd=false; } } } } std::cout<<"total="<<total<<std::endl; } }; int main() { raceTwo r; system("pause"); return 0; } 

 

测试例子

 

10

1 0 0 0 0 0 0 0 0 1

1 1 1 1 1 1 1 1 1 1

1 0 1 1 1 1 1 1 1 1

1 0 0 1 1 1 1 1 1 1

1 0 0 0 1 1 1 1 1 1

1 0 0 0 0 1 1 1 1 1

1 0 0 0 0 0 1 1 1 1

1 0 0 0 0 0 0 1 1 1

1 0 0 0 0 0 0 0 1 1

0 0 0 0 0 0 0 0 0 1

结果

 

2vs1

3vs1

3vs2

4vs1

4vs3

5vs1

5vs4

6vs1

6vs5

7vs1

7vs6

8vs1

8vs7

9vs1

9vs8

10vs1

total=16

10>1>9>8>7>6>5>4>3>2

 

5,方格

存在一个N*N的点阵,每个点都与上下左右相邻的点之间有一条有向边连接,但是这条有向边的放下为向左或者向下。每条有向边都有一个权值。左上角的点坐标为(1,1)其他的点向右,向下,坐标递增。每个点到(1,1)点的所有路径的长度都相等。给定一个长度,求这个点在该图上的坐标。但是每次都只能询问当前点到本列最右端和最下端之间的距离。

 

算法:

1,先从起始点开始向下一直查询直到下一个点到源点的距离大于给定的长度时停止

2,然后向右查找直到当前点的到源点的距离大于给定的长度为止

3,然后向上查找当前点到源点的距离,直到小于给定的长度为止

重复2,3过程,直到当前点到源点的距离等于给定的长度

输出坐标

 

同时在查找过程中,也可以输出每个当前点的坐标,作为查找的路径

#include "stdafx.h" #include <iostream> #include "SquarePro.h" SquarePro::SquarePro() { std::cin>>rows>>columns; g=new int*[rows+1]; for(int i=1;i<=rows;i++) g[i]=new int[columns+1]; for(int i=1;i<=rows;i++) for(int j=1;j<=columns;j++) std::cin>>g[i][j]; ci=1;cj=1; std::cin>>dist; currDis=0; get(right,up); lastRight=right; lastUp=up; k=1; while(dist!=currDis) { if(k==1)//k==1 bottom -1,up. 2 right,-2 left { while(currDis+lastUp-up<dist) { std::cout<<"("<<ci<<", "<<cj<<")"<<std::endl; currDis+=lastUp-up; lastUp=up; lastRight=right; ci++; get(right,up); } if(dist==currDis) { std::cout<<"("<<ci<<", "<<cj<<")"<<std::endl; system("exit"); } ci--; k=2; } if(k==2) { get(right,up); lastUp=up; lastRight=right; while(currDis+lastRight-right<dist) { dist+=lastRight-right; lastUp=up; lastRight=right; cj++; get(right,up); } if(dist==currDis) { std::cout<<"("<<ci<<", "<<cj<<")"<<std::endl; system("exit"); } k=-1; } if(k==-1) { SquarePro::get(right,up); lastUp=up; lastRight=right; while(currDis+lastUp-up>dist) { dist+=lastUp-up; lastUp=up; lastRight=right; ci--; get(right,up); } if(dist==currDis) { std::cout<<"("<<ci<<", "<<cj<<")"<<std::endl; system("exit"); } k=2; } } if(dist==currDis) { std::cout<<"("<<ci<<", "<<cj<<")"<<std::endl; system("exit"); } } void SquarePro::get(int &x, int &y) { int r,u; r=u=0; for(int i=ci;i<=rows;i++) { u+=g[i][cj]; } for(int j=cj;j<=columns;j++) { r+=g[ci][j]; } x=u; y=r; }  

 

以前做的一道题:最长词链,字典序词链。

忘了,又做了一遍~~~

#ifndef MAXWORDSPROBLEM_H #define MAXWORDSPROBLEM_H #include <string> struct PNode { int len;//统计词链所含的最多单词数 PNode *next[26];//以x字母结尾的单词词链的指针 }; class MaxWordsProblem { PNode *root;//词链初始指针 int n;//单词数 int ans;//最大词链单词数 public: MaxWordsProblem(); void update(std::string s); }; #endif 

#include "stdafx.h" #include <iostream> #include <string> #include "MaxWordsProblem.h" MaxWordsProblem::MaxWordsProblem() { std::cin>>n; ans=0; root->len=0; for(int i=0;i<26;i++) root->next[i]=NULL; std::string s; for(int i=0;i<n;i++) { std::cin>>s; MaxWordsProblem::update(s); } } void MaxWordsProblem::update(std::string s) { int x; int max=0; PNode * p=root; for(std::string::size_type i=0;i<s.size();i++) { x=s[i]-'a'; if(p->next[x]==NULL) { PNode * q=new PNode; q->len=0; for(int j=0;j<26;j++) q->next[j]=NULL; p->next[x]=q; } if(max<p->len) max=p->len; p=p->next[x]; } p->len=max+1; if(p->len>ans) ans=p->len; } 

你可能感兴趣的:(一些小题目)