269道各路算法考试题集锦

1 某编程大赛题(35,中等难度)

1、在实际的开发工作中,对于string的处理是最常见的编程任务,本题是要求程序对用户输入的string进行处理,具体要求如下: 1、每个单词的首字母变为大写。 2、将数字与字母之间用下划线隔开,使结构清晰。 3、多个空格变为1个空格。 示例:输入:you and me what cpp2005pragram 则输出:You And Me What Cpp_2005_Program 输入:this    is    a  99cat 则输出:This Is  A 99_Cat*/

2* A,B,C,D,E,F,G,H,I,J,10名学生有可能参加计算机竞赛,也可能不参加,因为某种原因他们受到下列条件的约束:1、 如果A参加,B也参加;   2、 如果C不参加,D也不参加;   3、 AC中只能有1个人参加;   4、 BD中有且仅有1个人参加;   5、 DEFG中至少有2人参加;   6、 CG或者都参加,或者都不参加;   7、 CEGI中至多只能2人参加      8、 如果E参加,那么FG也都参加。   9、 如果F参加,GH就不能参加   10、 如果IJ都不参加,H必须参加请编程根据这些条件判断10名同学参赛者名单比如LC D G J    代码在Num2

3 *要求找出具有下列性质的数的个数(包含输入的自然数n): 先输入1个自然数n(n<=500),然后对此自然数按照如下方法进行处理①、 不作任何处理;②、 在它的左边加上1个自然数,但该自然数不能超过原数首位数字的1③、 加上数后,继续按此要求进行处理,直到不能再加自然数为止、 样例:  输入:  6 满足条件的数为   6  16  26      126  36   136 输出:  6 */

private function fenjie(cnum: int, count: int , str: String): void{if(cnum == 0)return;if(count == max)trace(str);for (var i:int = cnum; i > 0; i--) {if(count + i > max)continue;fenjie(i, count +i, str + i);}} 

/*巧排数字。将1、2、...、20这20个数排成1排,使得相邻的两个数之和为1个素数,且首尾两数字之和也为1个素数。编程打印出所有的排法。*/

1楼房的楼梯级数很奇特,1步跨二级多1级,1步跨三级多二级,如果分用四、五、六、七去除级数分别余三、三、五、五。问这楼房共有多少级阶梯?(已知不超过400级)。  

狼追兔子,兔子躲进了10个环形分布的洞的某1个中。狼在第1个洞中没有找到兔子,就间隔1个洞,到第3个洞中去找,也没找到兔子,就间隔2个洞,到第6个洞中去找。以后狼每次多隔1个洞去找兔子,……。这样狼1直找不到兔子。请问兔子可能躲在哪个洞中?  

2、 1位数学家和1些游客共81人不幸落入强盗手中,强盗将俘虏排成1队,宣布每天处理所有第2N次方个俘虏(N>=0),而只放走剩下的最后1个。由于数学家身怀重任,不得不选择了1个恰当的位置而最终被放走。请问他归初排在第几个位置。  3、 有1堆礼物,工作人员无论是分成二个1份,还是三个、四个、五个、六个1份,总是多1个。请问这堆礼物至少多少个? public class Test9 {public static void main(String[] args) {//23456的最小公倍数int i =7;while(true){if(i%2==1&&i%3==1&&i%4==1&&i%5==1&&i%6==1){Systemoutprintln(i);break;}i=i+6;}}} 

4、 1付扑克中拿出所有的黑桃A……K按顺序排好。第1次翻出第1张牌——A,放在1边,再拿出第2张放到牌的最下面。以后每次都翻出1张牌,再将1张牌放到最后,问第八次翻出的牌是哪1张?

public class Test10 {public static void main(String[] args) {String a[]={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};List<String> list = new LinkedList<String>();int j;for (int i = 0; i < alength; i++) {listadd(a[i]);}for ( j = 0; j < 7; j++) { listremove(0);listadd(listremove(0));}Systemoutprintln(listget(0));}}package test;/*2、 1位数学家和1些游客共81人不幸落入强盗手中,强盗将俘虏排成1队,宣布每天处理所有第2N次方个俘虏(N>=0),而只放走剩下的最后1个。由于数学家身怀重任, 不得不选择了1个恰当的位置而最终被放走。请问他归初排在第几个位置。*/public class Test8 { /** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubint a[] = new int[81];for (int i = 0; i < alength; i++) {a[i] = i + 1;}// int b[] = a;int j = 0; int count = 0;while (count !=1) {count=0;for (int i = 0; i <= 6; i++) {a[(int) (Mathpow(2, i)) 1] = 0;// Systemoutprintln((int)Mathpow(2, i)); }for (int i = 0; i < alength; i++) { j=i;if (a[i] == 0) {for (int k = j + 1; k < alength; k++) {if (a[k] != 0) {a[i] = a[k];a[k]=0; // j = k;// Systemoutprintln("a["+i+"]="+a[i]+" "+"a["+k+"]="+a[k]);break;}}}}for (int i = 0; i < alength; i++) {if(a[i]!=0)count++;}}for (int i = 0; i < alength; i++) {if (a[i] != 0)Systemoutprintln(a[i]);}} }

package test; import javautilArrays;import javautilScanner; /*验证卡布列克常数,对于1个四位数N,进行下列运算:(1)将组成该四位数的4个数字由大到小排列,形成由这4个数字组成的最大的四位数; (2)将组成该四位数的4个数字由小到大排列,形成由这4个数字组成的最小的四位数(如果高位为0则取得的数不足4位); (3)求两个数的差,得到1个新的四位数(高位0保留),称为对N进行了1次卡布列克运算。有这样的规律: 对1个各位数字不全相同的四位数重复进行若干次卡布列克运算,最后得到的结果总是6174。这个数被称为卡布列克常数。N从键盘输入。 输出每1次的卡布列克运算及得到6174时的运算次数。*/public class Test11 {private static int count = 0; public static void main(String[] args) {Scanner sc = new Scanner(Systemin);Systemoutprintln("请输入1个不完全相同的四位数");String str = scnextLine();char c1[] = strtoCharArray();verify(c1);Arrayssort(c1);String strMin = StringcopyValueOf(c1);String strMax = "";for (int i = c1length - 1; i >= 0; i--) {strMax = strMax + c1[i];}// Systemoutprintln(strMax+" "+strMin);int max = IntegerparseInt(strMax);int min = IntegerparseInt(strMin);Systemoutprintln("max=" + max + " " + "min=" + min);kablk(strMax, strMin);} public static void verify(char[] c) {if (clength < 4 || clength > 4) {Systemoutprintln("长度不符合要求");Systemexit(0);}boolean flag = true;for (int i = 0; i < clength - 1; i++) {if (c[i] != c[i + 1]) {flag = false;break;}}if (flag) {Systemoutprintln("四位数完全相等");}} public static void kablk(String strMax, String strMin) {count++;int max = IntegerparseInt(strMax);int min = IntegerparseInt(strMin);int temp = max - min;if (temp == 6174) {Systemoutprintln("count="+count);} else if (temp > 0) { char c1[] = StringvalueOf(temp)toCharArray();Arrayssort(c1);strMin = StringcopyValueOf(c1);for (int i = c1length ; i < 4; i++) {strMin = "0" + strMin;}c1 = strMintoCharArray();// Systemoutprintln(c1);min = IntegerparseInt(strMin);strMax = "";for (int i = c1length - 1; i >= 0; i--) {strMax = strMax + c1[i];// Systemoutprintln(c1[i]);}max = IntegerparseInt(strMax);kablk(strMax, strMin);Systemoutprintln("max=" + max + " " + "min=" + min);} else {return;} }} 

1程序,从键盘输入数字R,计算机自动检查在下列算式的“()”中能否填上“+”或“-”号凑成相应的等式。如能凑成,则打印出这些算式。如不能则打印“NO ANSWER”。     1( )2( )3( )4( )5( )6( )7( )8( )9=R

“百钱买百鸡”是我国古代的著名数学题。题目这样描述:3文钱可以买1只公鸡,2文钱可以买1只母鸡,1文钱可以买3只小鸡。用100文钱买100只鸡,那么各有公鸡、母鸡、小鸡多少只?与之相似,有"鸡兔同笼"问题。

判断1string是否是回文数,如12112321ABA(string输入时以‘、’结束)如输入:12321输出:yes 

找数。1个三位数,各位数字互不相同,十位数字比个位、百位数字之和还要大,且十位、百位数字之和不是质数。编程找出所有符合条件的三位数。     注:1、 不能手算后直接打印结果。     2、 “质数”即“素数”,是指除1和自身外,再没有其它因数的大于1的自然数。 

 选人。1个小组共五人,分别为ABCDE。现有1项任务,要他们中的3个人去完成。已知:(1AC不能都去;2BC不能都不去;3)如果C去了,DE就只能去1个,且必须去1;4BCD不能都去;5)如果B去了,DE就不能都去。编程找出此项任务该由哪三人去完成的所有组合。 李润伟(22048303) 17:45:55 截数问题任意1个自然数,我们可以将其平均截取成三个自然数。示例自然数135768,可以截取成13,57,68三个自然数。如果某自然数不能平均截取(位数不能被3整除),可将该自然数高位补零后截取。现编程从键盘上输入1个自然数N(N的位数<12),计算截取后第1个数加第三个数减第2个数的结果。  

 试编程找出能被各位数字之和整除的1切两位数  

  1个正整数的个位数字是6,如果将个位数字移到首位,所得到的数是原数的4倍,试编程找出满足条件的最小正整数。  

  某本书的页码从1开始,小明算了算,总共出现了202个数1,试编程求这本书1共有多少页?  

30个男人女人和小孩同在1家饭馆进餐,共花了五十先令,其中男宾3先令,女宾2先令,小孩1先令。试编程求出男人女人小孩各多少人?  

编程找出四个互不相等的自然数它们之中任意两数之和为偶数,  任意三数之和可以被3整除而且这四个数的和越小越好(已知它们的和不大于50)、   

以不同的字母代表0--9之间的数字现有如下等式成立: a+bc+def=ghij,编程求出满足上述条件等式的个数并将所有等式打印输出、   

 下面的竖式表示图中的"*"号只能用素数2,3,5,7代替因此称为素数乘法竖式、       * * *     × * *       ---------------       * * * *    * * * *        ----------------    * * * * *  

1个四位数是1个完全平方数,减去1个每位数字都相同的四位数如 1111, 5555)仍是1个完全平方数、 请编程打印出所有这样的四位数、   

1个八位数12345679, 若它乘以9, 则得九位数111111111, 试求:素数   (1)当这个数乘以什么数时才能得到全部由5所组成的九位数?   (2)当这个数乘以什么数时才能得到全部由9所组成的九位数  

李先生和他的孙子同出生于20世纪他的孙子与他的年龄之差为60,  李先生和他的孙子出生年份被3,4,5,6余数分别为1,2,3,4、 编程求出李先生和他的孙子各出生在哪1年、   

 16/641个分子和分母都是两位数的真分数且分子的个位数与分母的十位数相同、 非常奇怪的是如果将该分数的分子的个位数和分母的十位数同时划去所得到的结果正好等于原分数约分后的结果、 例 16/64=1/4、 编程找出所有满足上述条件的真分数、   

 甲去买东西要付给乙19而甲只有31张的钱乙只有51张的钱、  请为他们设计1个交换方案、  

有六箱货物,重分别是5吨、2吨、35吨、17吨、1吨、51吨。现有1台货车,载重量10吨。设计1个程序,使这次车运走的货物最多。  

某电台组织1次智力竞赛,计划安排奖励30人。准备了50件奖品。得1等奖者可得3件,二等奖2件,三等奖1件。希望将所有奖品都发到获奖者手中。请找出所有方案(即各等奖各有多少人)。  

1个自然数是素数且它的数字位置经过任意对换后仍为素数称为绝对素数、  示例 13、  试找出所有这样的四位绝对素数  

1个自然数若它的质因数至少是两重的(相同的质因数至少个数为二个36=2*2*3*3)则称该数为"漂亮数"、  若相邻两个自然数都是"漂亮数", 就称它们为"孪生漂亮数"、 示例89就是1对、 请编程再找出1"孪生漂亮数"。   

某本书的页码从1开始,小明算了算,总共出现了202个数1,试编程求这本书1共有多少页?

 

public class Test3 {

 

/**

 * @param args

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

char buf[] = { 'a', 'b', 'c'};

int k = buf、length; // 选择几个字母排序

// char r[] = new char[k];

perm(0, buf, k); // 开始的字母在start,几个字母为k

 

}

 

public static void perm(int start, char[] buf, int k) {

if (start == k) { // 1个字母的全排列

for (int i = 0; i < k; i++) {

System、out、print(buf[i]);

}

System、out、println();

} else if (start < k) {// 多个字母全排列

for (int i = start; i < k; i++) {

char temp = buf[start]; // 交换数组的第1个元素和后续元素

buf[start] = buf[i];

buf[i] = temp;

perm(start + 1, buf, k); // 后续元素全排列

temp = buf[start]; // 还原

buf[start] = buf[i];

buf[i] = temp;

System、out、println("buf[start]="+buf[start]+" buf[i]="+buf[i]);

System、out、println("start="+start+" i="+i);

}

} else {

return;

}

}

 

}

 

 

 

任意输入二个自然数, 若商为整数, 则直接显示商; 否则将商分解成1个自然数和1个正的既约真分数之和才显示。 示例: 输入: 9, 3   显示: 9/3=3

 

          输入: 8, 6   显示: 8/6=1+1/3

 

 

 

任意输入四个自然数a,b,c,d, 看成二个分数a/b, c/d、 求这二个分数之和、  和的显示格式为: 输入 3,2,1,6    输出:  3/2+1/6=1+2/3。

 

 

在自然数中, 各位数字之和的11倍正好等于自身的自然数只有1个、 请找出这个自然数。

 

 

求所有不超过1000的这样的整数, 它的平方的末二位数字相同但不为0

Ecol<ecol0408@gmail、com>  9:51:18

package today;

 

import java、util、ArrayList;

import java、util、List;

 

public class help13 {

static List<Integer> count = new ArrayList<Integer>();

 

static boolean function(int num) {

for(int i=0;i<10000;i++){count、add(0);}

boolean bl = false;

int i = 2;

while (num > 1) {

if (num % i == 0) {

count、set(i-1,count、get(i-1)+1);

num /= i;

i = 2;

} else {

i++;

}

 

}

for (int k = 0; k < count、size(); k++) {

if (count、get(k) <2&&count、get(k)>0) {

//bl = true;

break;

}

if(k==count、size() 1){bl=true;}

 

}

count = null;

count = new ArrayList<Integer>();

return bl;

 

}

 

public static void main(String[] args) {

for (int i = 3; i <= 9999; i++) {

if (function(i) && function(i + 1)) {

System、out、println(i);

}

 

}

}

}

 

 

 

package test;

 

//1个正整数的个位数字是6,如果将个位数字移到首位,所得到的数是原数的4倍,试编程找出满足条件的最小正整数

public class Test16 {

 

public static void main(String[] args) {

// TODO Auto-generated method stub

String str = "";

int n = 0, m = 0;

int count = 1;

while (true) {

n = (int) Math、pow(10, count) + 6; //初始化为16,106,1006,10006,。。。。

for (int i = 1; i < 3;) {

str = String、valueOf(n);

String temp = str、substring(0, str、length() - 1);

str = str、substring(str、length() - 1) + temp;

m = Integer、valueOf(str);

if (m==n*4) {

System、out、println(n + " " + m);

System、exit(0);

}

n = n + 10;

i = (int) (n / Math、pow(10, str、length() - 1));//判断首位是否超过2

}

count++;

}

}

}

 

 

P是1个大于3的质数, 对某个自然数N, PN恰好是五位数,  且至少有三个位上的数字相同, 求P至少是多少。 

 

 

编程求最小正整数M,N(0<N<M)为何值时, 1989m与1989n的最后三位数字相同

 

 

验证下面结论: 1个各位数字不同且都不为0的N位数X(3<=N<=5), 将组成该数的各位数字重新排列成1个最大数和1个最小数作减法, 其差值再重复前述运算, 若干次后必出现1个N位数Y, 使之重复出现、 

 

示例: X=213, 则有 213→321-123=198      

 

      981-189=892

 

       982-289=693

 

       963-369=594

 

       954-459=495

 

       954-459=495

 

    这时Y=954、

 

 

 

 

package test;

 

import java、util、Scanner;

 

/*任意输入二个自然数, 若商为整数, 则直接显示商; 否则将商分解成1个自然数和1个正的既约真分数之和才显示。 示例: 输入: 9, 3   显示: 9/3=3

 

 输入: 8, 6   显示: 8/6=1+1/3*/

 

public class Test17 {

public static void main(String[] args) {

int a, b, n, m, l;

Scanner sc = new Scanner(System、in);

System、out、println("a=");

a = sc、nextInt();

System、out、println("b=");

b = sc、nextInt();

n = a / b; // 商的整数部分

m = a % b;// 余数

if (m != 0) // 不为0

{

l = Gcd(m, b); // 求出余数与被除数的最大公约数

m = m / l; // 分子;

b = b / l; // 分母

System、out、println(a + "/" + b + "=" + n + "+" + m + "/" + b);

} else

System、out、println(a + "/" + b + "=" + n);

}

 

static int Gcd(int m, int n) {

if (n == 0)

return m;

else

return Gcd(n, m % n);

}

}

 

 

任给1个自然数n,求出这个自然数不同因数的个数M

 

 

给出1个数n的不同因数个数m,求最小满足要求的自然数n,即n有m个不同的因数。

示例输入  2   则输出  2 因为2有2个因数。

 

 

 

m,n为自然数,其上限为k,试编写程序,由键盘输入自然数k找出满足条件:

 

  (n^2-mn-m^2)^2=1 且使m^2+n^2达到最大的m,n。

 

输出能被11整除且不含重复数字的三位数。并统计个数。

 

 

已知1个四位数为ABCD,若A+C和B+D的值相等,则称这个四位数为交叉数,求四位数的交叉数和个数。

 

 

定义

  2x6=12   2和6的积是12,因此2和6是12的因数。12是2的倍数,也是6的倍数。   3x4=12   3和4也是12的因数。12是3和4的倍数。   整数A乘以整数B得到整数C,整数A与整数B就称做整数C的因数,反之整数C就为整数A与整数B的倍数。

 

 

package eclip;

/*在自然数中, 各位数字之和的11倍正好等于自身的自然数只有1个、 请找出这个自然数。*/

public class Test4 {

public static long check(long num){

long temp=num;

long sum=0;

while(temp!=0){

sum+=temp%10;

temp=temp/10;

}

return sum*11;

}

public static void main(String[] args) {

long num=1;

while(true){

if(check(num)==num){

System、out、println(num);

break;

}

num++;

}

}

}

 

 

P是1个大于3的质数, 对某个自然数N, PN恰好是五位数,  且至少有三个位上的数字相同, 求P至少是多少。 

 

 

 

package ecol;

/*小明的妈妈是负责分发全厂工资的。

为使分发时有足够多的零钞,同时又

尽量不使每个人领到的钱太零碎。每

个月她都要计算出各种面值的钞票(

100元、50元、10元、5元、2元、1元,

假设每个人的工资都是整数元)各需要多少张

。你能否为她设计1个程序,从键盘输入10个人

的工资,再计算出各种面值的钞票各需要多少张?*/

 

public class mony {

static void function(int num){

int array[]=new int[5];

array[0]=100;

array[1]=50;

array[2]=10;

array[3]=5;

array[4]=2;

System、out、print(num+" = ");

for(int i=0;i<array、length;i++){

if(num/array[i]>0){System、out、print(num/array[i]+"*"+array[i]+(num%array[i]>0?"+":""));}

num%=array[i];

 

}

 

 

if((num/1)>0){System、out、println(num/1+"*"+1);}

 

}

 

 

public static void main(String[] args) {

function(12345);

 

}

}

 

 

输入1个string,将其中重复偶数次字符个数n,变为n/2,将重复奇数次字符个数m(m>=3),变为3*m+1,直到n=1,m=1,全部停止,输出每次做的1轮奇偶变化的string,示例:“gooddd”:

godddddddddd,goddddd,god、、、、d(16个d),godddddddd,godddd,godd,god

 

 

有1根长为514CM的钢筋,现在要截成23CM、15CM和19CM的短料,问在各至少截1根的前提下,问各截多少根,使所剩余料最少

 

package ecol;

 

import java、util、Scanner;

 

public class math {

static boolean function(int num){

boolean bl=false;int i;

for(i=2;i<=(int)Math、sqrt(num);i++){

 

if(num%i==0){break;}

 

 

}

if(i>(int)Math、sqrt(num)){bl=true;}

return bl;

 

}

 

static boolean function1(int num){

boolean bl=false;

int[]array=new int[10];

String str=""+num;

for(int i=0;i<str、length();i++){

array[Integer、parseInt(str、substring(i,i+1))]++;

 

 

}

for(int i=0;i<10;i++){

if(array[i]>=3){bl=true;break;}

 

}

return bl;

 

}

 

public static void main(String[] args) {

Scanner in=new  Scanner(System、in); 

int N=in、nextInt();

for(int i=10000;i<=99999;i++){

if(i%N==0&&function(i/N)&&function1(i)){System、out、println(i/N);break;}

 

 

 

}

 

 

}

}

 

 

随意生成10个整数(20以内,不重复,随机位置),每个数加上它所存储位置的下标的和为质数:

1、如果这10个整数,满足条件的超过5个,就输出

2、如果改为10以内的数,请输出满足条件的个数和整数排列

 

 

求能被11整除,且不含重复数字的三位数?有多少个,并输出(注重算法效率)

 

 

求2~1000中的完数,(因子和等于它本身的数为完数。示例28的因子是1,2,4,7,14,且1+2+4+7+14=28,则28是完数)。

 

 

找2~1000中的亲密数对(如果A 的因子和等于B,B的因子和等于A,且A不等于B,则称A,B为亲密数对)。

 

 

有1个三位数,三个数字和为20,第三个数 3倍与第2个数的2倍及第1个数三者之和为44,第1个数与第2个数和的2倍减去第三个烽的4倍为-14,求这个三位数。

 

 

父子二人,已知儿子年龄不大于40岁,父亲年龄不大于100岁,10年前父亲的年龄是儿子年龄的4倍,10年后父亲的年龄是儿子年龄的整数倍。问父子现年多少岁

 

 

纯粹素数是这样定义的:1个素数,去掉最高位,剩下的数仍为素数,再去掉剩下的数的最高位,余下的数还是素数。这样下去1直到最后剩下的个位数也还是素数。求出所有小于3000的四位纯粹素数。

 

 

求n个最小的连续合数。合数是除了1和本身以外还有其它因子的正整数。

 

输入样例:3

 

输出样例: 8 9 10

 

 

 

 

大家熟知鸡兔同笼问题,输入两个数a,b,a为脚的只数,b为头的个数。编程序输出鸡的只数和兔的只数。

 

 

求圆周率π≈1-1/3+1/5-1/7+…+(-1)n-11/(2n-1),求π的近似值,真到某项的绝对值小于10-6为止

 

 

编写出打印出右边数字方阵的程序。

 

1 2 3 4 5 6

 

2 3 4 5 6 7

 

3 4 5 6 7 8 

 

5 6 7 8 9 10

 

6 7 8 9 10 11

 

 

找出1~100之间的全部“同构数”。“同构数”是这样1种数:它出现在它的平方数的右端。示例:5的平方是25,5就是同构数,25也是构数。

 

 

用筛法求1 到10000的素数

 

 

有从1到n依次编号的n个人和n盏灯。我号人将所有的灯都关掉;2号人将编号为2的倍数的灯都打开;3号人则将编号为3的倍数的灯作相反处理;以后的人都将凡是自己编号的倍数的灯作相反处理。问第n个人操作后,哪些灯是打开的?

 

 

运动会连续开了n天,1共发了m枚奖章,第1天发1枚并剩下(m-1)枚的1/7,第2天发2枚并剩下的1/7,以后每天按此规律发奖章,在最后1天即第n天发了剩下的n枚奖章。问运动会开了多少天?1共发了几枚奖章?

 

 

设有1个数组A:array [0、、N-1] of integer; 存放的元素为0~N-1(1<N<=10)之间的整数,且A[i]≠A[j](i≠j)。示例当N=6时,有:A=(4,3,0,5,1,2)。此时,数组A的编码定义如下:

 

A[0]编码为0;

 

A[i]编码为:在A[0],A[1],…,A[i-1]中比A[i]的值小的个数

 

  (i=1,2,…,N-1)

 

∴上面数组A的编码为:B=(0,0,0,3,1,2)

 

    要求编程解决以下问题:

 

(1)给出数组A后,求出其编码;

 

(2)给出数组A的编码后,求出A中的原数据

 

程序样例:

例1:

输入:Stat=1   {表示要解决的第(1)问题}

 

   N=8  {输入8个数}

 

   A=1 0 3 2 5 6 7 4

 

输出:B=0 0 2 2 4 5 6 4

 

例二:

输入:Stat=2   {表示要解决的第(2)问题}

 

   N=7

 

   B=0 1 0 0 4 5 6  

 

输出:A=2 3 1 0 4 5 6

 

 

 

矩阵相乘:已知N×M1矩阵A和M1×M矩阵B(1≤M、M1、N≤10),求矩阵C(=A×B)。示例:

 

输入:N,M1,M=4  3  4

 

  A= 1   2    3     

 

3     4    5     提示:所谓矩阵相乘(如A×B=C),是指

 

4     5    6    Cij= ∑(Aik×Bkj)(i=1~N,j=1~M1,k=1~M)

 

5     –1  –2       

 

   B= 1   6    4    2    示例:

 

      2   3    4    1     C11=A11×B11+A12×B21+A13×B31

 

    –1   5    7   –3      =1×1+2×2+3×(– 1)

 

输出:C= 2   27   33   –5     =2

 

     6   55   63   –5    C42= A41×B12+A42×B22+A43×B32

 

     8   69   78   –5      =5×6+(–1)×3+(–2)×5

 

     5   17   2    15   =17

 

 

 

输入N(2≤N≤100)个数字(在0与9之间),然后统计出这组数中相邻两数字组成的链环数字对出现的次数。示例:

 

输入:N=20  {表示要输入数的数目}

 

  0  1  5  9  8  7  2  2  2  3  2  7  8  7  8  7  9  6  5  9   

 

输出:(7,8)=2 (8,7)=3 {指(7,8)、(8,7)数字对出现次数分别为2次、3次)

 

 (7,2)=1 (2,7)=1

 

 (2,2)=2

 

 (2,3)=1 (3,2)=1

 

 

 

生成1个按蛇形方式排列自然数1,2,3,4,5,……,N2的 (1<N≤10)阶方阵。示例:

 

输入:N=4     N=7

 

输出: 1   3    4   10   1    3    4   10   11   21   22

 

   2   5    9   11   2    5    9   12   20   23   34

 

   6   8   12   15   6    8   13   19   24   33   35

 

   7   13  14   16   7   14   18   25   32   36   43

 

        15   17   26   31   37   42   44

 

        16   27   30   38   41   45   48

 

        28   29   39   40   46   47   49

 

IT公司招录算法题(120,难度不分级)

1、题目描述:

    对输入的n个数进行排序并输出。

输入:

    输入的第1行包括1个整数n(1<=n<=100)

    接下来的1行包括n个整数。

输出:

    可能有多组测试数据,对于每组数据,将排序后的n个整数输出,每个数后面都有1个空格。

    每组测试数据的结果占1行。

样例输入:

4

1 4 3 2

样例输出:

1 2 3 4

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

int main()

{

 int n;

 while(cin>>n&&n>=1&&n<=100)

 {

  vector<int> ivec;

  int itemp;

  for(int i=0;i<n;i++)

  {

   cin>>itemp;

   ivecpush_back(itemp);

  }

  sort(ivecbegin(),ivecend());

  for(vector<int>::iterator j=ivecbegin();j!=ivecend();j++)

   cout<<*j<<' ';

  cout<<endl;

 }

 return 0;

}

2、有N个学生的数据,将学生数据按成绩高低排序,如果成绩相同则按姓名字符的字母序排序,如果姓名的字母序也相同则按照学生的年龄排序,并输出N个学生排序后的信息。

输入:

    测试数据有多组,每组输入第1行有1个整数NN<=1000),接下来的N行包括N个学生的数据。

    每个学生的数据包括姓名(长度不超过100string)、年龄(整形数)、成绩(小于等于100的正数)。

输出:

    将学生信息按成绩进行排序,成绩相同的则按姓名的字母序进行排序。

    然后输出学生信息,按照如下格式:

    姓名 年龄 成绩

样例输入:

3

abc 20 99

bcd 19 97

bed 20 97

样例输出:

bcd 19 97

bed 20 97

abc 20 99

#include<stdioh>

#include<stringh>

struct student

{

 char name[101];

 int age;

 int score;

};

int main()

{

 int n,i,j;

 struct student a[1000],temp;

 while(scanf("%d",&n)!=EOF)

 {

  for(i=0;i<n;i++)

  {

   scanf("%s %d %d",&a[i]name,&a[i]age,&a[i]score);

  }

  for(i=1;i<n;i++)

  {

   for(j=1;j<=n-i;j++)

   {

    if(a[j-1]score>a[j]score)

    {

     temp=a[j-1];

     a[j-1]=a[j];

     a[j]=temp;

    }

    else if(a[j-1]score==a[j]score)

    {

     if(strcmp(a[j-1]name,a[j]name)>0)

     {

      temp=a[j-1];

      a[j-1]=a[j];

      a[j]=temp;

     }

     else if(strcmp(a[j-1]name,a[j]name)==0)

     {

      if(a[j-1]age>a[j]age)

      {

       temp=a[j-1];

       a[j-1]=a[j];

       a[j]=temp;

      }

     }

    }

   }

  }

  for(i=0;i<n;i++)

  {

   printf("%s %d %d\n",a[i]name,a[i]age,a[i]score);

  }

 }

 return 0;

}

4、 题目描述:

输入1系列整数,将其中最大的数挑出,并将剩下的数进行排序。

输入:

输入第1行包括1个整数N1<=N<=1000,代表输入数据的个数。

接下来的1行有N个整数。

输出:

可能有多组测试数据,对于每组数据,

1行输出1个整数,代表N个整数中的最大值,并将此值从数组中去除,将剩下的数进行排序。

2行将排序的结果输出。

样例输入:

4

1 3 4 2

样例输出:

4

1 2 3

#include <stdioh>

int main(){

int i,n,t,j,a[1000];

while(scanf("%d",&n)!=EOF){

 for(i=0;i<n;i++){

  scanf("%d",&a[i]);

  t=a[i];

  j=i-1;

  while(j>=0&&a[j]>t) {a[j+1]=a[j];j--;}

  a[j+1]=t;

 }

printf("%d\n",a[n-1]);

if(n==1) printf("-1\n");

else for(i=0;i<n-1;i++){

 printf("%d",a[i]);

 if(i!=n-2) printf(" ");

 else printf("\n");}

}

return 0;

}

5、 题目描述:

    Excel可以对1组纪录按任意指定列排序。现请你编写程序实现类似功能。

    对每个测试用例,首先输出1行“Case i:”,其中 是测试用例的编号(从1开始)。随后在 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 

时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

输入:

    测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (N<=100000) 和 C,其中 是纪录的条数,是指定排序的列号。以下有N行,每行包含1条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的string)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。

输出:

    对每个测试用例,首先输出1行“Case i:”,其中 是测试用例的编号(从1开始)。随后在 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 

时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

样例输入:

3 1

000007 James 85

000010 Amy 90

000001 Zoe 60

4 2

000007 James 85

000010 Amy 90

000001 Zoe 60

000002 James 98

4 3

000007 James 85

000010 Amy 90

000001 Zoe 60

000002 James 90

0 0

样例输出:

Case 1:

000001 Zoe 60

000007 James 85

000010 Amy 90

Case 2:

000010 Amy 90

000002 James 98

000007 James 85

000001 Zoe 60

Case 3:

000001 Zoe 60

000007 James 85

000002 James 90

000010 Amy 90

#include <iostream>

#include <fstream>

#include <string>

#include <algorithm>

using namespace std;

struct info{

 string id;

 string name;

 int score;

};

bool cmp_id(const struct info a,const struct info b)

{

 return aid<bid;

}

bool cmp_name(const struct info a,const struct info b)

{

 if(aname==bname)

 return aid<bid;

 else

 return aname<bname;

}

bool cmp_score(const struct info a,const struct info b)

{

 if(ascore==bscore)

 return aid<bid;

 else

 return ascore<bscore;

}

int main(int argc, char **argv)

{

//ifstream cin("inputtxt");

 int n,c,count=0;

 while(cin>>n>>c)

 {

  if(n==0&&c==0)

  break;

  count++;

  struct info data[n];

  for(int i=0;i<n;i++)

  cin>>data[i]id>>data[i]name>>data[i]score;

  switch(c)

  {

   case 1:

   sort(data,data+n,cmp_id);

   break;

   case 2:

   sort(data,data+n,cmp_name);

   break;

   case 3:

   sort(data,data+n,cmp_score);

  }

  printf("Case %d:\n",count);

  for(int i=0;i<n;i++)

   printf("%s %s %d\n",data[i]idc_str(),data[i]namec_str(),data[i]score);

  } 

}

6、题目描述:

输入1string,长度小于等于200,然后将输出按字符顺序升序排序后的string

输入:

测试数据有多组,输入string

输出:

对于每组输入,输出处理后的结果。

样例输入:

bacd

样例输出:

Abcd

#include<stdioh>

#include<stringh>

int main()

{

 char string[200],temp;

 int i,j,n;

 while(scanf("%s",string)!=EOF)

 {

  n=0;

  while(string[n])

  {

   n++;

  }

  for(i=1;i<n;i++)

  {

   for(j=0;j<n-i;j++)

   {

    if((string[j]-string[j+1])>0)

    {

     temp=string[j];

     string[j]=string[j+1];

     string[j+1]=temp;

    }

   }

  }

  printf("%s\n",string);

 }

 return 0;

}

7、 题目描述:

有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天

输入:

有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD

输出:

每组数据输出1行,即日期差值

样例输入:

20110412

20110422

样例输出:

11

#include<stdioh>

#include<mathh>

#define MAX_DATE_SIZE 9

int Days[12]={31,28,31,30,31,30,31,31,30,30,31};

typedef struct Date

{

    int Year;

    int Month;

    int Day;

}Date;

int main(int argc,char *argv)

{

    int i,L;

    int HLN1,HLN2;

    int sDay,eDay;

    Date sDate,eDate;

    char sdate[MAX_DATE_SIZE],edate[MAX_DATE_SIZE];

    

    while(scanf("%s",sdate)!=EOF)

    {

 sDay=0;

 eDay=0;

 //日期格式转化

 sDateYear=(sdate[0]-'0')*1000+(sdate[1]-'0')*100+(sdate[2]-'0')*10+(sdate[3]-'0');

 sDateMonth=(sdate[4]-'0')*10+(sdate[5]-'0');

 sDateDay=(sdate[6]-'0')*10+(sdate[7]-'0');

 scanf("%s",edate);

 eDateYear=(edate[0]-'0')*1000+(edate[1]-'0')*100+(edate[2]-'0')*10+(edate[3]-'0');

 eDateMonth=(edate[4]-'0')*10+(edate[5]-'0');

 eDateDay=(edate[6]-'0')*10+(edate[7]-'0');

 HLN1=(int)(sDateYear/4) (int)(sDateYear/100)+(int)(sDateYear/400);

 HLN2=(int)(eDateYear/4) (int)(eDateYear/100)+(int)(eDateYear/400);

 for(i=0;i<sDateMonth-1;++i) sDay+=Days[i];

 for(i=0;i<eDateMonth-1;++i) eDay+=Days[i];

 sDay+=sDateDay;

 eDay+=eDateDay;

 L=(int)fabs((sDateYear*365+HLN1+sDay) (eDateYear*365+HLN2+eDay))+1;

 printf("%d\n",L);

    }

    return 1;

}

8、 题目描述://蔡勒公式

计算星期几公式

#include<iostream>

usingnamespacestd;

intmain(){

intyear,month,day;

while(cin>>year>>month>>day){

if(month<3{

year-=1;

month+=12;

}

charb[7][10]={"sunday","monday","tuesday","wednesday","thursday","friday","saturday"};

intc=int(year/100),y=year-100*c;

intw=int(c/4) 2*c+y+int(y/4+26*(month+1/10+day-1;

w=(w%7+7%7;

cout<<b[w]<<endl;

We now use the Gregorian style of dating in Russia、 The leap years are years with number divisible by 4 but not divisible by 100, or divisible by 400

For example, years 2004, 2180 and 2400 are leap、 Years 2004, 2181 and 2300 are not leap

Your task is to write a program which will compute the day of week corresponding to a given date in the nearest past or in the future using today’s agreement about dating

输入:

There is one single line contains the day number d, month name M and year number y(1000y3000)、 The month name is the corresponding English name starting from the capital letter

输出:

Output a single line with the English name of the day of week corresponding to the date, starting from the capital letter、 All other letters must be in lower case

样例输入:

9 October 2001

14 October 2001

样例输出:

Tuesday

Sunday

#include<iostream>

#include<cstring>

using namespace std;

int main()

{

    char month[12][20]={"January","February","March","April","May","June","July","August","September","October","November","December"};//egg broken、、、 

    string week[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};

    int m_day[12]={0,3,3,6,1,4,6,2,5,0,3,5};

    int l_day[12]={0,3,4,0,2,5,0,3,6,1,4,6};

    int year,day,m,ans;

    char mon[20];

    while(cin>>day>>mon>>year)

    {

 int i;

 for(i=0;i<12;i++)

 {

     if(strcmp(month[i],mon)==0)

  m=i;

 }

 if((year%4==0&&year%100!=0)||(year%400==0))

     ans=(year+year/4+year/400-year/100-2+l_day[m]+day)%7;

 else

     ans=(year+year/4+year/400-year/100-1+m_day[m]+day)%7;

 cout<<week[ans]<<endl;

    }

    return 0;

}

9、 题目描述:

输入年、月、日,计算该天是本年的第几天。

输入:

包括三个整数年(1<=Y<=3000)、月(1<=M<=12)、日(1<=D<=31)

输出:

输入可能有多组测试数据,对于每1组测试数据,

输出1个整数,代表Input中的年、月、日对应本年的第几天。

样例输入:

1990 9 20

2000 5 1

样例输出:

263

122

#include <iostream>

using namespace std;

bool fun(int year,int month)

{

 if((year%400==0||(year%4==0&&year%100!=0))&&month>2)return true;//是闰年且月份大于2

 else return false;

}

int main()

{

 int y,m,d;

 while(cin>>y>>m>>d)

 {

  if(y<1||y>3000||m<1||m>12||d<1||d>31)return 1;

  int sum=0;

  switch(m)

  {

  case 12: sum+=30;

  case 11: sum+=31;

  case 10: sum+=30;

  case 9: sum+=31; 

  case 8: sum+=31; 

  case 7: sum+=30; 

  case 6: sum+=31; 

  case 5: sum+=30; 

  case 4: sum+=31; 

  case 3: sum+=28; 

  case 2: sum+=31; 

  default:break;

  }

  sum+=d;

  if(fun(y,m))sum++;

  cout<<sum<<endl;

 }

 return 0;

}

10、 题目描述:

给出年分m1年中的第n天,算出第n天是几月几号。

输入:

输入包括两个整数y(1<=y<=3000)n(1<=n<=366)

输出:

可能有多组测试数据,对于每组数据,

按 yyyy-mm-dd的格式将输入中对应的日期打印出来。

样例输入:

2000 3

2000 31

2000 40

2000 60

2000 61

2001 60

样例输出:

2000-01-03

2000-01-31

2000-02-09

2000-02-29

2000-03-01

2001-03-01

#include <stdioh>

#include <stdlibh>

#include <stringh>

void showFormatdate(int, int);

int main()

{

 int year, dates;

 while(scanf("%d %d", &year, &dates) != EOF)

 {

  showFormatdate(year, dates);

 }

}

void showFormatdate(int year, int dates)

{

 int sum, i, m, d;

 int month[12] = {31,28,31,30,31,30,31,31,30,31,30,31};

 if((year % 100 == 0) && (year % 400 == 0) || (year % 4 == 0) && (year % 100 != 0))

 {

  //润年

  month[1] = 29;

 }

  

 for(i = 0, sum = 0; i < 12; i ++)

 {

  if(sum < dates)

  {

   sum += month[i];

  }else

  {

   break;

  }

 }

 //获取月份

 m = i;

 //获取当月的天数

 d = month[i - 1] - (sum - dates);

 //格式化输出

 printf("%04d-%02d-%02d\n",year, m, d);

}

11、 题目描述:

读入N名学生的成绩,将获得某1给定分数的学生人数输出。

输入:

测试输入包含若干测试用例,每个测试用例的格式为

1行:N

2行:N名学生的成绩,相邻两数字用1个空格间隔。

3行:给定分数

当读到N=0时输入结束。其中N不超过1000,成绩分数为(包含)0100之间的1个整数。

输出:

对每个测试用例,将获得给定分数的学生人数输出。

样例输入:

3

80 60 90

60

2

85 66

0

5

60 75 90 55 75

75

0

样例输出:

1

0

2

#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std;

double t[1005],a;

int N;

int main()

{

 int i;

 while(cin>>N && N)

 {

  int ans = 0;

  for(i = 0; i<N; i++)

   cin>>t[i];

  cin>>a;

  for(i = 0; i<N; i++)

  if(t[i] == a)ans++;

  cout<<ans<<endl;

 }

 return 0;

}

12、 题目描述:

    输入1ip地址串,判断是否合法。

输入:

    输入的第1行包括1个整数n(1<=n<=500),代表下面会出现的IP地址的个数。

    接下来的n行每行有1IP地址,IP地址的形式为abcd,其中abcd都是整数。

输出:

    可能有多组测试数据,对于每组数据,如果IP地址合法则输出"Yes!”,否则输出"No!”。

样例输入:

2

255255255255

5121223

样例输出:

Yes!

No!

提示:

合法的IP地址为:

abcd都是0-255的整数。

#include <iostream>

 

using namespace std;

 

int main(){

    int n;

    int p1,p2,p3,p4;

    while (cin>>n)

    {

 for(int i=0;i<n;i++)

 {

 

 char c;

 cin>>p1>>c>>p2>>c>>p3>>c>>p4;

     if(p1>=0 && p2>=0 && p3>=0 && p4>=0 && p1<=255 && p2<=255 && p3<=255 && p4<=255){

     cout<<"Yes!"<<endl;

     }

     else{

     cout<<"No!"<<endl;

     }

 }

    }

    return 0;

}

13、 题目描述:

给你n个整数,请按从大到小的顺序输出其中前m大的数。

输入:

每组测试数据有两行,第1行有两个数n,m(0<n,m<1000000),第2行包含n个各不相同,且都处于区间[-500000,500000]的整数。

输出:

对每组测试数据按从大到小的顺序输出前m大的数。

样例输入:

5 3

3 -35 92 213 -644

样例输出:

213 92 3

#include <cstdio>

#include <algorithm>

#include <functional>

 

using namespace std;

 

#define left(i) ((i + 1) * 2 - 1)

#define right(i) (left(i) + 1)

#define parent(i) ((i + 1) / 2)

 

void heapify(int a[], int n, int index)

{

    while (true) {

 int i = index;

 int l = left(i), r = right(i);

 if (l < n) {

     i = a[i] < a[l] ? i : l;

 }

 if (r < n) {

     i = a[i] < a[r] ? i : r;

 }

 if (i != index) {

     std::swap(a[i], a[index]);

     index = i;

 } else {

     break;

 }

    }

}

 

void make_heap(int a[], int n)

{

    for (int i = parent(n - 1); i >= 0; --i) {

 heapify(a, n, i);

    }

}

 

int main()

{

    int n, m;

    while (scanf("%d %d", &n, &m) != EOF) {

 int *a = new int[m];

 for (int i = 0; i < m; ++i) {

     scanf("%d", &a[i]);

 }

 make_heap(a, m);

 int num;

 for (int i = m; i < n; ++i) {

     scanf("%d", &num);

     if (num > a[0]) {

  a[0] = num;

  heapify(a, m, 0);

     }

 }

 sort(a, a + m, greater<int>());

 printf("%d", a[0]);

 for (int i = 1; i < m; ++i) {

     printf(" %d", a[i]);

 }

 printf("\n");

    }

    return 0;

}

14、题目描述:

    “臭味相投”——这是我们描述朋友时喜欢用的词汇。两个人是朋友通常意味着他们存在着许多共同的兴趣。然而作为1个宅男,你发现自己与他人相互了解的机会并不太多。幸运的是,你意外得到了1份北大图书馆的图书借阅记录,于是你挑灯熬夜地编程,想从中发现潜在的朋友。

    首先你对借阅记录进行了1番整理,将N个读者依次编号为1,2,,N,将M本书依次编号为1,2,,M。同时,按照“臭味相投”的原则,和你喜欢读同1本书的人,就是你的潜在朋友。你现在的任务是从这份借阅记录中计算出每个人有几个潜在朋友。

输入:

    每个案例第1行两个整数N,M2 <= N M<= 200。接下来有N行,第i(i = 1,2,,N)行每1行有1个数,表示读者i-1最喜欢的图书的编号P(1<=P<=M)

输出:

    每个案例包括N行,每行1个数,第i行的数表示读者i有几个潜在朋友。如果i和任何人都没有共同喜欢的书,则输出“BeiJu”(即悲剧,^ ^

样例输入:

4  5

2

3

2

1

样例输出:

1

BeiJu

1

BeiJu

#include <iostream>

#include <set>

 

using namespace std;

 

int main(void)

{

 multiset<int> record;

 int N, M;

 int ss[200];

 

 while (cin >> N >> M)

 {

  for (int i=0; i < N; i++)

  {

   cin >> ss[i];

   recordinsert(ss[i]);

  }

   

  for (int i=0; i < N; i++)

  {

   if (recordcount(ss[i]) == 1)

   {

    cout << "BeiJu" << endl;

   }

   else

   {

    cout << recordcount(ss[i]) 1 << endl;

   }

  }

   

  recordclear();

 }

 

 

 return 0;

}

15、 题目描述:

M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)51115是同1种分法。

输入:

1行是测试数据的数目t0 <= t <= 20)。以下每行均包含二个整数MN,以空格分开。1<=MN<=10

输出:

对输入的每组数据MN,用1行输出相应的K

样例输入:

1

7 3

样例输出:

8

#include <iostream>

using namespace std;

int f(int m,int n)

{

 if(n==1)

  return 1;

 else if(m==1||m==0)

  return 1;

 else if(m<0)

  return 0;

 else 

  return f(m,n-1)+f(m-n,n);

}

int main()

{

 int m,n;

 int t;

 cin>>t;

 while(t--)

 {

  cin>>m>>n;

  cout<<f(m,n)<<endl;

 }

 return 0;

}

16、 有1个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L1个线段,起点是坐标原点,在每个整数坐标点有1棵树,即在0,1,2,、、、,LL+1个位置上有L+1棵树。

    现在要移走1些树,移走的树的区间用1对数字表示,如 100 200表示移走从100200之间(包括端点)所有的树。

    可能有M(1<=M<=100)个区间,区间之间可能有重叠。现在要求移走所有区间的树之后剩下的树的个数。

输入:

    两个整数L(1<=L<=10000)M(1<=M<=100)

    接下来有M组整数,每组有1对数字。

输出:

    可能有多组输入数据,对于每组输入数据,输出1个数,表示移走所有区间的树之后剩下的树的个数。

样例输入:

500 3

100 200

150 300

470 471

#include <stdioh>

#define MAXLEN 10001

int main(){

#ifdef ONLINE_JUDGE

#else

freopen("E:\\intxt", "r", stdin);

#endif

 int L[MAXLEN];

 int l, m;

 while (scanf ("%d%d", &l, &m) != EOF){

  for (int i = 0; i <= l; i++){ //注意i的范围是i<=l not i<l

   L[i] = 1;

  }// 初始化,种l+1棵树

  

  int a, b;

  for (int i = 1; i <= m; i++){

   scanf("%d%d", &a, &b);

   for(int j = a; j <= b; j++){

    L[j] = 0;

   }// 移走

  }// m

  

  int left=0;

  for (int i = 0; i <= l; i++){

   if (L[i] == 1)

    left++;

  }

  printf("%d\n", left);

 }// while:zu

 return 0;

}

17、 题目描述:

输入1个高度h,输出1个高为h,上底边为h的梯形。

输入:

1个整数h(1<=h<=1000)

输出:

h所对应的梯形。

样例输入:

4

样例输出:

  ****

    ******

  ********

**********

#include<stdioh>

#include<stringh>

 

int main(void)

{

 int h;

 while(scanf("%d",&h) != EOF)

 {

  int i,j;

  for(i = 1; i <= h; ++i)

  {

   for(j = 1; j <= 2 * h - 2 * i; ++j)

    printf(" ");

   for(j = 2 * h - 2 * i + 1; j <= 3 * h - 2; ++j)

    printf("*");

   printf("\n");

  }

 }

 return 0;

}

18、 题目描述:

1个个大小差1圈的筐叠上去,使得从上往下看时,边筐花色交错。这个工作现在要让计算机来完成,得看你的了。

输入:

输入是1个个的三元组,分别是,外筐尺寸nn为满足0<n<80的奇整数),中心花色字符,外筐花色字符,后二者都为ASCII可见字符;

输出:

输出叠在1起的筐图案,中心花色与外筐花色字符从内层起交错相叠,多筐相叠时,最外筐的角总是被打磨掉。叠筐与叠筐之间应有1行间隔。

样例输入:

11 B A 

5 @ W

样例输出:

 AAAAAAAAA

ABBBBBBBBBA

ABAAAAAAABA

ABABBBBBABA

ABABAAABABA

ABABABABABA

ABABAAABABA

ABABBBBBABA

ABAAAAAAABA

ABBBBBBBBBA

 AAAAAAAAA

#include <stdioh>

#include <malloch>

int main(){

    int n;

    char pic[80][80];

    char first, second;

 

    while(scanf("%d %c %c", &n, &first, &second) != EOF){

 

 int min, max, floor = 0;

 for(min = max = n / 2 ;min>=0&&max<n; min--, max++, floor ++)

 {

     char c = floor%2==0? first:second;

     for(int j = min; j<=max; j++){

  pic[min][j] =c;

  pic[max][j] =c;

  pic[j][max] =c;

  pic[j][min] =c;

     }

 }

 if(n > 1)    pic[0][0] = pic[0][n-1] = pic[n-1][0] =pic[n-1][n -1] = ' ';

 

 //print pattern

 for(int i = 0; i< n; i ++){

     for(int j = 0 ; j < n; j++){

  printf("%c", pic[i][j]);

     }

     printf("\n");

 }

 printf("\n");

    }

}

19、 题目描述:

Harmony is indispensible in our daily life and no one can live without it----may be Facer is the only exception、 One day it is rumored that repeat painting will create harmony and then hundreds of people started their endless drawing、 Their paintings were based on a small template and a simple method of duplicating、 Though Facer can easily imagine the style of the whole picture, but he cannot find the essential harmony、 Now you need to help Facer by showing the picture on computer

You will be given a template containing only one kind of character and spaces, and the template shows how the endless picture is created----use the characters as basic elements and put them in the right position to form a bigger template, and then repeat and repeat doing that、 Here is an example

# #

 #  <-template

# #

So the Level 1 picture will be

# #

 #

# #

Level 2 picture will be

# # # #

 #  #

# # # #

 # #   

  #    

 # #   

# #    # #

 # # 

# #    # #

输入:

The input contains multiple test cases

The first line of each case is an integer N, representing the size of the template is N*N (N could only be 3, 4 or 5)

Next N lines describe the template

The following line contains an integer Q, which is the Scale Level of the picture

Input is ended with a case of N=0

It is guaranteed that the size of one picture will not exceed 3000*3000

输出:

For each test case, just print the Level Q picture by using the given template

样例输入:

3

# #

 # 

# #

1

3

# #

 # 

# #

3

4

 OO 

O  O

O  O

 OO 

2

0

样例输出:

# #

 # 

# #

# #   # #  # #   # #

 # #    # # 

# #   # #  # #   # #

   # #    # #   

    #   #    

   # #    # #   

# #   # #  # #   # #

 # #    # # 

# #   # #  # #   # #

  # #   # #  

   # #   

  # #   # #  

     # #     

  #  

     # #     

  # #   # #  

   # #   

  # #   # #  

# #   # #  # #   # #

 # #    # # 

# #   # #  # #   # #

   # #    # #   

    #   #    

   # #    # #   

# #   # #  # #   # #

 # #    # # 

# #   # #  # #   # #

 OO  OO 

    O  OO  O    

    O  OO  O    

 OO  OO 

 OO   OO 

O  O O  O

O  O O  O

 OO   OO 

 OO   OO 

O  O O  O

O  O O  O

 OO   OO 

 OO  OO 

    O  OO  O    

    O  OO  O    

 OO  OO

#include <iostream>

#include <stdioh>

#include <algorithm>

#include <string>

#include <stringh>

#include <functional>

#include <vector>

#include <cmath>

using namespace std;

 

void shape_str2char(string src[] , char* dest[], int x, int y, int n){

 for(int i=0; i<n; i++)

  for(int j=0; j<n; j++)

   dest[x+i][y+j]=src[i]at(j);

}

 

void shape_char2char(char* src[], char* dest[], int x, int y, int n){

 for(int i=0; i<n; i++)

  for(int j=0; j<n; j++)

   dest[x+i][y+j]=src[i][j];

}

 

void shape_recur(int depth, char* templ[], char* dest[], int x, int y, int size){

 if(depth==1)

  shape_char2char(templ, dest, x, y, size);

 else{

  for(int i=0; i<size; i++)

   for(int j=0; j<size; j++)

    if(templ[i][j]!=' ')

     shape_recur(depth-1, templ, dest, x+i*pow(double(size), depth-1), y+j*pow(double(size), depth-1), size);

 }

}

 

int main(){

 int size_templ;

 while(scanf("%d", &size_templ) && size_templ!=0){

  //sp1

  while(getchar() != '\n')

   continue;

  char* str[6];

  for(int i=0; i<6; i++) str[i] = new char[6];

  for(int i=0; i<size_templ; i++) gets(str[i]);

  //sp2

  char* templ[6];

  for(int i=0; i<6; i++) templ[i] = new char[6];

  shape_char2char(str, templ, 0, 0, size_templ);

  //sp3

  int num;

  scanf("%d", &num);

  int size_pic = pow((double)size_templ, num);

  char *Pic[3001];

  for(int i=0; i<3001; i++) Pic[i] = new char[3001];

  for(int i=0; i<3001; i++)

   for(int j=0; j<3001; j++)

    Pic[i][j]=' ';

 

  shape_recur(num, templ, Pic, 0, 0, size_templ);

  //sp4

  for(int i=0; i<size_pic; i++){

   for(int j=0; j<size_pic; j++)

    printf("%c", Pic[i][j]);

   printf("\n");

  }

  for(int i=0; i<6; i++) delete(str[i]);

  for(int i=0; i<3001; i++) delete(Pic[i]);

 }

}

20、 题目描述:

输入1个数n,然后输入n个数值各不相同,再输入1个值x,输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1)。

输入:

测试数据有多组,输入n(1<=n<=200),接着输入n个数,然后输入x

输出:

对于每组输入,请输出结果。

样例输入:

2

1 3

0

样例输出:

-1

#include <stdioh>

 

int main()

{

 int n;

 while (scanf("%d",&n)!=EOF)

 {

  int x,a[200],fla=0;

  for (int i=0;i<n;i++)

  {

   scanf("%d",&a[i]);

  }

  scanf("%d",&x);

  for (int i=0;i<n;i++)

  {

   if (a[i]==x)

   {

    printf("%d\n",i);

    fla=1;

    break;

   }    

  }

  if (fla==0)

  {

   printf("-1\n");

  }

 }

 return 0;

}

21、 题目描述:

 输入N个学生的信息,然后进行查询。

输入:

 输入的第1行为N,即学生的个数(N<=1000)

接下来的N行包括N个学生的信息,信息格式如下:

01 李江 男 21

02 刘唐 男 23

03 张军 男 19

04 王娜 女 19

然后输入1M(M<=10000),接下来会有M行,代表M次查询,每行输入1个学号,格式如下:

02

03

01

04

输出:

 输出M行,每行包括1个对应于查询的学生的信息。

如果没有对应的学生信息,则输出“No Answer!

样例输入:

4

01 李江 男 21

02 刘唐 男 23

03 张军 男 19

04 王娜 女 19

5

02

03

01

04

03

样例输出:

02 刘唐 男 23

03 张军 男 19

01 李江 男 21

04 王娜 女 19

03 张军 男 19

#include<iostream>

#include<fstream>

#include<algorithm>

#include<string>

#include<map>

using namespace std;

 

int main()

{

 string id,info,str;

 int i,index,n,M;

 map<string,string> m;

    map<string,string>::iterator iter;

// fstream cin("1069txt");

 while (cin>>n)

 {

  cinignore();

  mclear();

  for (i=0;i<n;i++)

  {

   getline(cin,str);

   index=strfind(" ");

   id=strsubstr(0,index);

   info=strsubstr(index+1);

   minsert(pair<string,string>(id,info));

  }

  cin>>M;

  for (i=0;i<M;i++)

  {

   cin>>id;

   iter=mfind(id);

   if (iter!=mend())

   {

    cout<<iter->first<<" "<<iter->second<<endl;

   }

   else

   {

    cout<<"No Answer!"<<endl;

   }

  }

 }

 return 0;

}

22、 题目描述:

1个整数数组上,对于下标为i的整数,如果它大于所有它相邻的整数,

或者小于所有它相邻的整数,则称为该整数为1个极值点,极值点的下标就是i

输入:

每个案例的输入如下:

2×n+1行输入:第1行是要处理的数组的个数n;

对其余2×n行,第1行是此数组的元素个数k(4<k<80),第2行是k个整数,每两个整数之间用空格分隔。

输出:

每个案例输出为n行:每行对应于相应数组的所有极值点下标值,下标值之间用空格分隔。

样例输入:

3

10

10 12 12 11 11 12 23 24 12 12

15

12 12 122 112 222 211 222 221 76 36 31 234 256 76 76 

15

12 14 122 112 222 222 222 221 76 36 31 234 256 76 73

样例输出:

0 7

2 3 4 5 6 10 12

0 2 3 10 12 14

#include<iostream>

#include<vector>

using namespace std;

int main()

{

 int n;

 while(cin >> n)

 {

  while(n--)

  {

   int k,i;

   cin >> k;

   vector<int> vv(k);

   for(i = 0;i < k;i++) cin >> vv[i];

   vector<int> out;

   outreserve(k);

   if(vv[0] < vv[1]||vv[0] > vv[1]) outpush_back(0);

   for(i = 1;i <= k-2;i++)

   {

    if(vv[i] > vv[i-1]&&vv[i] > vv[i+1]) outpush_back(i);

    if(vv[i] < vv[i-1]&&vv[i] < vv[i+1]) outpush_back(i);

   }

   if(vv[k-1] < vv[k-2]||vv[k-1] > vv[k-2]) outpush_back(k-1);

   for(i = 0;i < outsize() - 1;i++) cout << out[i] << " ";

   cout << out[i] << endl;

  }

 }

 return 0;

}

23、 题目描述:

输入数组长度 

输入数组  a[1、、、n] 

输入查找个数

输入查找数字b[1、、、m] 

 

输出 YES or NO  查找有则YES 否则NO 

输入:

输入有多组数据。

每组输入n,然后输入n个整数,再输入m,然后再输入m个整数(1<=m<=n<=100)。

输出:

如果在n个数组中输出YES否则输出NO

样例输入:

5

1 5 2 4 3

3

2 5 6

样例输出:

YES

YES

NO

#include<iostream>

#include<vector>

#include<algorithm>

using namespace std;

int main()

{

 int temp,i,n,m;

 vector<int> v;

 while (cin>>n)

 {

  for (i=0;i<n;i++)

  {

   cin>>temp;

   vpush_back(temp);

  }

  cin>>m;

  for (i=0;i<m;i++)

  {

   cin>>temp;

   vector<int>::iterator index=find(vbegin(),vend(),temp);//刚学的iterator迭代器用法,并使用系统提供的find方法

   if (index==vend())

   {

    cout<<"NO"<<endl;

   }

   else

   {

    cout<<"YES"<<endl;

   }

  } 

 }

 return 0;

}

23、 题目描述:

FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean

The warehouse has N rooms、 The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food、 FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food、 Here a is a real number、 Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain、 

输入:

The input consists of multiple test cases、 Each test case begins with a line containing two non-negative integers M and N、 Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively、 The last test case is followed by two -1's、 All integers are not greater than 1000

输出:

For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain

样例输入:

5 3

7 2

4 3

5 2

20 3

25 18

24 15

15 10

-1 -1

样例输出:

13333

31500

#include <cstdio>

#include <vector>

#include <algorithm>

 

using namespace std;

 

struct Room {

    int beans;

    int cost;

    double ratio;

};

 

struct Cmp {

    bool operator()(const Room &a, const Room &b) {

 return aratio > bratio;

    }

};

 

int main()

{

    Cmp cmp;

    int food, n;

    while (scanf("%d %d", &food, &n) != EOF && food != -1) {

 vector<Room> rooms;

 for (int i = 0; i < n; ++i) {

     Room room;

     scanf("%d %d", &roombeans, &roomcost);

     roomratio = roombeans / (double)roomcost;

     roomspush_back(room);

 }

 sort(roomsbegin(), roomsend(), cmp);

 int index = 0;

 double beans = 00;

 while (food && index < n) {

     Room &room = rooms[index];

     if (food >= roomcost) {

  food -= roomcost;

  beans += roombeans;

  ++index;

     } else {

  double ratio = food / (double)roomcost;

  beans += roombeans * ratio;

  break;

     }

 }

 printf("%3f\n", beans);

    }

    return 0;

}

24、 题目描述:

“今年暑假不AC?”“是的。”“那你干什么呢?”“看世界杯呀,笨蛋!”“@#$%^&*%、、、”确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视作为球迷,1定想看尽量多的完整的比赛,当然,作为新时代的好青年,你1定还会看1些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)

输入:

输入数据包含多个测试实例,每个测试实例的第1行只有1个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用1个正整数表示。n=0表示输入结束,不做处理。

输出:

对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占1行。

样例输入:

12

1 3

3 4

0 7

3 8

15 19

15 20

10 15

8 18

6 12

5 10

4 14

2 9

0

样例输出:

5

#include <cstdio>

#include <algorithm>

using namespace std;

 

struct ss{

    int st,ed;

}node[102];

 

bool cmp(ss x,ss y){

    if(xed!=yed)  return xed<yed;

    else    return xst>yst;

}

 

int main(){

    int n;

    while(scanf("%d",&n)!=EOF){

 if(n==0)    return 0;

 else{

     for(int i=0;i<n;++i){

  scanf("%d %d",&node[i]st,&node[i]ed);

     }

     sort(node,node+n,cmp);

     int num=1,k=0;

     for(int j=0;j<n;j++){

  if(node[j]st>=node[k]ed){

      num++;

      k=j;

  }

     }

     printf("%d\n",num);

 }

    }

}

24、 题目描述:

通过悬崖的yifenfei,又面临着幽谷的考验——

幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,1旦吸入体内,便会全身溃烂而死。

幸好yifenfei早有防备,提前备好了解药材料(各种浓度的万能药水)。现在只需按照配置成不同比例的浓度。

现已知yifenfei随身携带有n种浓度的万能药水,体积V都相同,浓度则分别为Pi%。并且知道,针对当时幽谷的瘴气情况,只需选择部分或者全部的万能药水,然后配置出浓度不大于 W%的药水即可解毒。

现在的问题是:如何配置此药,能得到最大体积的当前可用的解药呢?

特别说明:由于幽谷内设备的限制,只允许将1种已有的药全部混入另1种之中(即:不能出现对1种药只取它的1部分这样的操作)。

输入:

输入数据的第1行是1个整数C,表示测试数据的组数;

每组测试数据包含2行,首先1行给出三个正整数n,V,W(1<=n,V,W<=100);

接着1行是n个整数,表示n种药水的浓度Pi%(1<=Pi<=100)

输出:

对于每组测试数据,请输出1个整数和1个浮点数;

其中整数表示解药的最大体积,浮点数表示解药的浓度(四舍五入保留2位小数);

如果不能配出满足要求的的解药,则请输出0 000

样例输入:

3

1 100 10

100

2 100 24

20 30

3 100 24

20 20 30

样例输出:

0 000

100 020

300 023

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <cmath>

 

using namespace std;

 

int main()

{

 int c;

 cin >> c;

 for(;c>0;c--)

 {

  int n,v,w;

  cin >> n >> v >> w;

  int buf[100];

  for(int i=0;i<n;i++)

   cin >> buf[i];

  sort(buf,buf+n);//解药按浓度排序

  int currW = 0;

  int currV = 0;

  for(int i=0;i<n;i++)

  {

   if(buf[i] <= w)

   {

    currW = (buf[i]*v + currW);

    currV += v;

   }

   else

    if((buf[i]*v + currW) <= w*(currV+v))

    {

     currW = currW + buf[i]*v;

     currV += v;

    }

    else

     break;

  }

  cout << currV << " 0";

  currW = floor((double)currW/currV + 05);

  if(currV == 0)currW = 0;

  printf("%02d",currW);

  cout << endl;

 }

 //system("pause");

}

25、 题目描述:

Long time ago , Kitty lived in a small village、 The air was fresh and the scenery was very beautiful、 The only thing that troubled her is the typhoon

When the typhoon came, everything is terrible、 It kept blowing and raining for a long time、 And what made the situation worse was that all of Kitty's walls were made of wood

One day, Kitty found that there was a crack in the wall、 The shape of the crack is 

a rectangle with the size of 1×L (in inch)、 Luckly Kitty got N blocks and a saw(锯子) from her neighbors

The shape of the blocks were rectangle too, and the width of all blocks were 1 inch、 So, with the help of saw, Kitty could cut down some of the blocks(of course she could use it directly without cutting) and put them in the crack, and the wall may be repaired perfectly, without any gap

Now, Kitty knew the size of each blocks, and wanted to use as fewer as possible of the blocks to repair the wall, could you help her ?

输入:

The problem contains many test cases, please process to the end of file( EOF )

Each test case contains two lines

In the first line, there are two integers L(0<L<1000000000) and N(0<=N<600) which

mentioned above

In the second line, there are N positive integers、 The ith integer Ai(0<Ai<1000000000 ) means that the ith block has the size of 1×Ai (in inch)

输出:

For each test case , print an integer which represents the minimal number of blocks are needed

If Kitty could not repair the wall, just print "impossible" instead

样例输入:

5 3

3 2 1

5 2

2 1

样例输出:

2

Impossible

#include<stdioh>

#include<algorithm>

using namespace std;

bool cmp(int a,int b)

{

  return a>b;

}

int main()

{

  int i,N;

  long long L,A[601];

  while(scanf("%lld%lld",&L,&N)!=EOF)

  {

    for(i=0;i<N;i++)

    {

  scanf("%lld",&A[i]);

    }

    sort(A,A+N,cmp);

    bool flag=true;

    int sum=0,k=0;

    for(i=0;i<N;i++)

    {

  if((sum+A[i])<L)

  {

 k++;

 sum+=A[i];

  }

  else

  {

 k++;

 flag=false;

 break;

  }

    }

    if(flag)

    {

  printf("impossible\n");

    }

    else

    {

  printf("%d\n",k);

    }

  }

    return 0;

}

26、 题目描述:

With highways available, driving a car from Hangzhou to any other city is easy、 But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time、 Different gas station may give different price、 You are asked to carefully design the cheapest route to go

输入:

For each case, the first line contains 4 positive numbers: Cmax (<= 100), the maximum capacity of the tank; D (<=30000), the distance between Hangzhou and the destination city; Davg (<=20), the average distance per unit gas that the car can run; and N (<= 500), the total number of gas stations、 Then N lines follow, each contains a pair of non-negative numbers: Pi, the unit gas price, and Di (<=D), the distance between this station and Hangzhou, for i=1,、、、N、 All the numbers in a line are separated by a space

输出:

For each test case, print the cheapest price in a line, accurate up to 2 decimal places、 It is assumed that the tank is empty at the beginning、 If it is impossible to reach the destination, print "The maximum travel distance = X" where X is the maximum possible distance the car can run, accurate up to 2 decimal places

样例输入:

50 1300 12 8

600 1250

700 600

700 150

710 0

720 200

750 400

730 1000

685 300

50 1300 12 2

710 0

700 600

样例输出:

74917

The maximum travel distance = 120000

#include <stdioh>  

#include <stdlibh>  

#include <mathh>  

    

#define MAXN 501  

#define MAXC 300000000  

    

typedef struct station{  

    float price;  

    int dist;  

}Station;  

    

int compare(const void * p, const void * q){  

    Station * p1 = (Station *)p;  

    Station * q1 = (Station *)q;  

    return p1->dist - q1->dist;  

}  

    

int main(void){  

    int Cmax, D, Davg, N;  //ÈÝÁ¿¡¢¾àÀ롢ÿµ¥Î»ÆøÐÐÊ»µÄ¾àÀë¡¢¼ÓÆøÕ¾×ÜÊý  

    int i;  

    Station sta[MAXN];  

    float sum, remind_gas, tmp;  

    int k, step;  

    

    while (scanf("%d %d %d %d", &Cmax, &D, &Davg, &N) != EOF){  

 for (i=0; i<N; ++i){  

     scanf("%f %d", &sta[i]price, &sta[i]dist);  

 }  

 sta[N]dist = D;  

 sta[N]price = 10000000;  

 qsort(sta, N, sizeof(Station), compare);  //°´Ó뺼ÖݾàÀë´óС¸ø¼ÓÆøÕ¾ÅÅÐò  

 if (sta[0]dist > 0){  

     printf ("The maximum travel distance = 000\n");  

     continue;  

 }  

 sum = 0;  //×Ü·ÑÓà 

 step = Cmax*Davg;    //¼ÓÂúÓÍÐÐÊ»×î´ó¾àÀë  

 remind_gas = 0;  //Ê£ÓàÓÍÁ¿  

 for (i=0; i<N; ++i){  

     k = i+1;  

     if (i != 0)  

  remind_gas -= ((float)(sta[i]dist -sta[i-1]dist))/Davg;  

     for (; k<N && sta[k]price>=sta[i]price; ++k)  

  continue;  

     if (sta[k]dist-sta[i]dist > step){  

  sum += (Cmax-remind_gas)*sta[i]price;  

  remind_gas = Cmax;  

     }  

     else{  

  tmp = ((float)(sta[k]dist-sta[i]dist))/Davg - remind_gas;  

  if (fabs(tmp)>1e-5 && tmp>0){  

      sum += tmp*sta[i]price;  

      remind_gas = ((float)(sta[k]dist-sta[i]dist))/Davg;  

  }  

     }  

     if (sta[i+1]dist - sta[i]dist > step){  

  printf ("The maximum travel distance = %2f\n", (float)(sta[i]dist+step));  

  break;  

     }  

 }  

 if (i == N){  

     printf ("%2f\n", sum);  

 }  

    }  

    

    return 0;  

}  

27、 题目描述:

    在某个string(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子1样)任何1个左括号都从内到外与在它右边且距离最近的右括号匹配。写1个程序,找到无法匹配的左括号和右括号,输出原来string,并在下1行标出不能匹配的括号。不能匹配的左括号用"$"标注,不能匹配的右括号用"?"标注、

输入:

    输入包括多组数据,每组数据1行,包含1string,只包含左右括号和大小写字母,string长度不超过100

    注意:cingetline(str,100)最多只能输入99个字符!

输出:

    对每组输出数据,输出两行,第1行包含原始输入字符,第2行由"$","?"和空格组成,"$""?"表示与之对应的左括号和右括号不能匹配。

样例输入:

)(rttyy())sss)(

样例输出:

)(rttyy())sss)(

?     ?$

#include<stdioh>

#include<stringh>

#include<stdlibh>

 

#define MAX_LEN 110

 

int main(void)

{

 char *exp=(char*)malloc(sizeof(char)*MAX_LEN);

 int *res=(int*)malloc(sizeof(int)*MAX_LEN);

 while(gets(exp))

 {

  int cur=0,pt=0,len=strlen(exp);

  for(int i=0;i!=MAX_LEN;++i)

   res[i]=-1;

  for(;cur!=len;++cur)

  {

   if(exp[cur]!='('&&exp[cur]!=')')

    res[cur]=0;

   if(exp[cur]==')')

   {

    for(pt=cur-1;pt>=0;--pt)

    {

     if(exp[pt]=='('&&res[pt])

     {

      res[pt]=0;

      res[cur]=0;

      break;

     }

    }

   }

  }

  puts(exp);

  for(int i=0;i!=len;++i)

  {

   if(exp[i]=='('&&res[i]==-1)

    res[i]=1;

   else if(exp[i]==')'&&res[i]==-1)

    res[i]=2;

   switch(res[i])

   {

   case 0:

    putchar(' ');

    break;

   case 1:

    putchar('$');

    break;

   case 2:

    putchar('?');

    break;

   }

  }

  printf("\n");

 }

 return 0;

}

28、 题目描述:

    读入1个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

输入:

    测试输入包含若干测试用例,每个测试用例占1行,每行不超过200个字符,整数和运算符之间用1个空格分隔。没有非法表达式。当1行中只有0时输入结束,相应的结果不要输出。

输出:

    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。

样例输入:

1 + 2

4 + 2 * 5 - 7 / 11

0

样例输出:

300

1336

#include <stdioh>

#include <stringh>

#include <stdlibh>

 

#define size 500

 

int isfu(char a){

 return (a=='*' || '-'==a || '+'==a || '/'==a);

}

int isdig(char a){

 return a>='0' && a <= '9';

}

 

int mygets(char *s, int *len)

{

 char ch;

 (*len) = 0; 

 while ('\n' != (ch=getchar()))/*输入处理*/

 {

  if (isfu(ch)||isdig(ch))

   s[(*len)++] = ch;

 } 

 s[*len] = 0;

 if ((*len) == 1 && s[0] == '0') return 0;

 return 1;

}

 

main()

{

 char str[size], fu[size];

 int i, len, nd, nf, total,now; 

 double dig[size];

 

 while (mygets(str,&len))

 {  

  if (len == 0) continue;

  nd = nf = now = 0;

  for (i = 0; i < len; )

  {

   if (isfu(str[i]))

   {

     

    fu[nf++] = str[i];

    if ('*' == str[i] || '/' == str[i])    

     now = 1;/*得到下1个数后马上计算*/

    i++;

   }

   else

   {

    total = 0;

    while (str[i] >= '0' && str[i] <= '9')

    {

      total *= 10;

      total += (str[i] - '0') ;

      i++;

    }

  

    dig[nd++] = (double)total;

    if (now)

    {/*立马算*/

     nf--, nd--;

     if ('*' == fu[nf])

      dig[nd-1] = dig[nd-1] * dig[nd];

     else if ('/' == fu[nf])    

      dig[nd-1] = dig[nd-1] / dig[nd];

      

     now = 0;

    }

   }

  }

  i = 0;

  while (i<nd-1)/*只剩加减法*/

  {

   if ('-' == fu[i]) dig[i+1] = dig[i] - dig[i+1];

   else if ('+' == fu[i]) dig[i+1] +=  dig[i];   

   i++;

  }

  printf("%2lf\n",dig[nd-1]);

 }

}

29、 题目描述:

    堆栈是1种基本的数据结构。堆栈具有两种基本操作方式,push 和 popPush1个值会将其压入栈顶,而 pop 则会将栈顶的值弹出。现在我们就来验证1下堆栈的使用。

输入:

 对于每组测试数据,第1行是1个正整数 n0<n<=10000(n=0 结束)。而后的 行,每行的第1个字符可能是'P’或者'O’或者'A;如果是'P’,后面还会跟着1个整数,表示将这个数据压入堆栈;如果是'O’,表示将栈顶的值 pop 出来,如果堆栈中没有元素时,忽略本次操作;如果是'A’,表示询问当前栈顶的值,如果当时栈为空,则输出'E'。堆栈开始为空。

输出:

    对于每组测试数据,根据其中的命令字符来处理堆栈;并对所有的'A’操作,输出当时栈顶的值,每个占据1行,如果当时栈为空,则输出'E’。当每组测试数据完成后,输出1个空行。

样例输入:

3

A

P 5

A

4

P 3

P 6

A

0

样例输出:

E

5

3

#include<iostream>

#include<fstream>

#include<vector>

#include<stack>

 

using namespace std;

int main()

{

 int i,n,temp;

 char ch;

 vector<int> v;

 stack<int> s;

// fstream cin("1108txt");

 while (cin>>n,n)

 {

  vclear();

  for (i=0;i<n;i++)

  {

   cin>>ch;

   switch(ch)

   {

   case 'A':

    if (vempty())

    {

     cout<<"E"<<endl;

    }

    else

    {

     cout<<vback()<<endl;

    }

    break;

   case 'P':

    {

     cin>>temp;

     vpush_back(temp);

    }

    break;

   case 'O':

    {

     if (!vempty())

     {

      vpop_back();

     }

    }

    break;

   }

  }

  cout<<endl;

 }

 

 return 0;

}

30、 题目描述:

对于1个不存在括号的表达式进行计算

输入:

存在多种数据,每组数据1行,表达式不存在空格

输出:

输出结果

样例输入:

6/2+3+3*4

样例输出:

18

#include <iostream>

#include <stack>

using namespace std;

 

string str;

int pos;

 

double getNum(){

    double v = 0;

    for(;pos<strlength();pos++){

 if(str[pos]>'9'||str[pos]<'0'){

     break;

 }

 v *= 10;

 v += str[pos] - '0';

    }

    return 10*v;

}

 

int main(int argc,char* argv[]){

    double a,b;

    double v;

    while(cin>>str){

 stack<double> s;

 pos = 0;

 spush(getNum());

 while(pos<strlength()){

     if(str[pos]=='*'){

  pos++;

  a = stop();

  spop();

  b = getNum();

  spush(a*b);

     }

     if(str[pos]=='/'){

  pos++;

  a = stop();

  spop();

  b = getNum();

  spush(a/b);

     }

     if(str[pos]=='+'){

  pos++;

  spush(getNum());

     }

     if(str[pos]=='-'){

  pos++;

  spush(-10*getNum());

     }

 }

 v = 0;

 while(!sempty()){

     v += stop();

     spop();

 }

 cout<<v<<endl;

    }

    return 0;

}

31、 题目描述:

哈夫曼树,第1行输入1个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。

输入:

输入有多组数据。

每组第1行输入1个数n,接着输入n个叶节点(叶节点权值不超过1002<=n<=1000)。

输出:

输出权值。

样例输入:

5  

1 2 2 5 9

样例输出:

37

#include <iostream>

#include <algorithm>

using namespace std;

int main()

{

    int n;

    while(cin>>n){

    int sum=0;

    int a[n];

    for(int i=0;i<n;i++)

    cin>>a[i];

    for(int i=1;i<n;i++)

    {

     sort(a+i-1,a+n);

     sum=a[i]+a[i-1]+sum;

     a[i]=a[i]+a[i-1];

     }

    cout<<sum<<endl;   

     }

    return 0;

}

32、 题目描述:

    在1个果园里,小明已经将所有的水果打了下来,并按水果的不同种类分成了若干堆,小明决定将所有的水果合成1堆。每1次合并,小明可以将两堆水果合并到1起,消耗的体力等于两堆水果的重量之和。当然经过 n次合并之后,就变成1堆了。小明在合并水果时总共消耗的体力等于每次合并所耗体力之和。

    假定每个水果重量都为 1,并且已知水果的种类数和每种水果的数目,你的任务是设计出合并的次序方案,使小明耗费的体力最少,并输出这个最小的体力耗费值。示例有 种水果,数目依次为 129。可以先将 1堆合并,新堆数目为3,耗费体力为 3。然后将新堆与原先的第三堆合并得到新的堆,耗费体力为 12。所以小明总共耗费体力=3+12=15,可以证明 15 为最小的体力耗费值。

输入:

    每组数据输入包括两行,1行是1个整数 n(1<=n<=10000),表示水果的种类数,如果 等于 表示输入结束,且不用处理。第2行包含 个整数,用空格分隔,第 个整数(1<=ai<=1000)是第 种水果的数目。

输出:

对于每组输入,输出1个整数并换行,这个值也就是最小的体力耗费值。输入数据保证这个值小于 2^31

样例输入:

3

9 1 2

0

样例输出:

15

#include<iostream>

using namespace std;

 

int main(int argc,char* argv[])

{

 int n;

 int a[10000];

 int temp;

 int i,j;

 int t,k;

 int sum;

 while(cin>>n&&n!=0)

 {

  sum=0;

  for(i=0;i<n;i++)

  {

   cin>>a[i];

  }

  t=n-1;

  while(t>0)

  {

   k=0;

   for(i=0;i<=t;i++)

    if(a[k]>a[i])

     k=i;

     temp=a[t];

   a[t]=a[k];

   a[k]=temp;  //a[t]为第1个最小值

  

   k=0;

   for(i=0;i<=t-1;i++)

    if(a[k]>a[i])

     k=i;

     temp=a[t-1];

   a[t-1]=a[k];

   a[k]=temp;  //a[t-1]为第2个最小值

 

   a[t-1]+=a[t];

   t--;

   sum+=a[t];

  }

  cout<<sum<<endl;

 

 }

 return 0;

}

33、 题目描述:

二叉树的前序、中序、后序遍历的定义:

前序遍历:对任1子树,先访问跟,然后遍历其左子树,最后遍历其右子树;

中序遍历:对任1子树,先遍历其左子树,然后访问根,最后遍历其右子树;

后序遍历:对任1子树,先遍历其左子树,然后遍历其右子树,最后访问根。

给定1棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯1确定后序遍历)。

输入:

两个string,其长度n均小于等于26

1行为前序遍历,第2行为中序遍历。

二叉树中的结点名称以大写字母表示:ABC、、、、最多26个结点。

输出:

输入样例可能有多组,对于每组测试样例,

输出1行,为后序遍历的string

样例输入:

ABC

BAC

FDXEAG

XDEFAG

样例输出:

BCA

XEDGAF

#include <stdioh>

#include <stringh>

#include <stdlibh>

char s1[101],s2[101];

int a[101];

int k;

void fen(char *s2,int l,int h);

main()

{

   

  int i,j;

  while( scanf("%s %s",s1,s2) != EOF){

  k = -1;

  for(i = 0;i < strlen(s1);i++){

     for(j = 0;j < strlen(s2);j++){

    if(s1[i] == s2[j]) a[i] = j;

    }

     }

   

  fen(s2,0,strlen(s2) - 1);

   

  printf("\n");

  }

}

 

void fen(char *s2,int l,int h){

 int n;

 if(h < l) return ;

 if(h - l > 0) k++;

 n = a[k];

 if(l == h) {

   printf("%c",s2[h]);

   k++;

   return ;

   }

 fen(s2,l,n-1);

 fen(s2,n+1,h);    

 printf("%c",s2[n]);

 }

34、 题目描述:

 

    如上所示,由正整数123……组成了1颗特殊二叉树。我们已知这个二叉树的最后1个结点是n。现在的问题是,结点m所在的子树中1共包括多少个结点。

    比如,n = 12m = 3那么上图中的结点131415以及后面的结点都是不存在的,结点m所在子树中包括的结点有36712,因此结点m的所在子树中共有4个结点。

输入:

    输入数据包括多行,每行给出1组测试数据,包括两个整数mn (1 <= m <= n <= 1000000000)。最后1组测试数据中包括两个0,表示输入的结束,这组数据不用处理。

输出:

    对于每1组测试数据,输出1行,该行包含1个整数,给出结点m所在子树中包括的结点的数目。

样例输入:

3 12

0 0

样例输出:

4

#include <mathh>

#include <stdioh>

int main()

{

 unsigned long n,sum=0,d;

 while(scanf("%d",&d))

 {

  unsigned long i;

  scanf("%d",&n);

  if (d==0&&n==0) break;

  unsigned long ddeep;

  ddeep=(unsigned long)(log(d)/log(2)+1);

  unsigned long d1,d2;

  d1=(unsigned long)(log(n)/log(2)+1);

  if(d>n)

  {

   printf("0\n");break;

  }   

  else

  {

   unsigned long j,k;

   k=d;

   unsigned long count=0;

      for(i=ddeep; i<d1-1; i++)

   {

    count++;

    k=2*k+1;

    for(j=d*pow(2,count);j<=k;j++)

    {

     sum++;

    }     

   }   

   count++;

   k=2*k+1;

   for (j=d*pow(2,count);j<=k&&j<=n;j++)

   {

    sum++;

   }   

  }

  printf("%d\n",++sum);

  sum=0;

 }

 return 0;

}

35、 题目描述:

1棵树,输出某1深度的所有节点,有则输出这些节点,无则输出EMPTY。该树是完全二叉树。

输入:

输入有多组数据。

每组输入1n(1<=n<=1000),然后将树中的这n个节点依次输入,再输入1d代表深度。

输出:

输出该树中第d层得所有节点,节点间用空格隔开,最后1个节点后没有空格。

样例输入:

4

1 2 3 4

2

样例输出:

2 3

#include<iostream>

#include<algorithm>

#include<string>

#include<vector>

#include<cmath>

#include<fstream>

 

using namespace std;

int main()

{

 

 int i,n,d,temp,sum1,sum2;

 vector<int> v;

// fstream cin("1176txt");

 while (cin>>n)

 {

  vclear();

  for (i=0;i<n;i++)

  {

   cin>>temp;

   vpush_back(temp);

  }

   

  cin>>d;

   

  sum1=pow(2,d-1) 1;

  sum2=pow(2,d) 1;

  if (sum1>=n)

  {

   cout<<"EMPTY"<<endl;

  }

  else if (n>sum1&&n<sum2)

  {

   cout<<vat(sum1);

   for (i=sum1+1;i<n;i++)

   {

    cout<<" "<<vat(i);

   }

  }

  else if (n>=sum2)

  {

   cout<<vat(sum1);

   for (i=sum1+1;i<sum2;i++)

   {

    cout<<" "<<vat(i);

   }

  }

  cout<<endl;

 }

  

 

 return 0;

}

36、 题目描述:

    输入1系列整数,建立二叉排序数,并进行前序,中序,后序遍历。

输入:

    输入第1行包括1个整数n(1<=n<=100)

    接下来的1行包括n个整数。

输出:

    可能有多组测试数据,对于每组数据,将题目所给数据建立1个二叉排序树,并对二叉排序树进行前序、中序和后序遍历。

    每种遍历结果输出1行。每行最后1个数据之后有1个空格。

样例输入:

5

1 6 5 9 8

样例输出:

1 6 5 9 8 

1 5 6 8 9 

5 8 9 6 1

#include <iostream>

using namespace std;

 

typedef struct Node

{

 int data;

 struct Node *leftchild;

 struct Node *rightchild;

}BTree,*Blink;

 

 

//前序遍历

void PreOrder(Blink head)

{

 if(head)

 {

  cout << head->data << " ";

  PreOrder(head->leftchild);

  PreOrder(head->rightchild);

 }

}

 

//中序遍历

void InOrder(Blink head)

{

 if(head)

 {

  InOrder(head->leftchild);

  cout << head->data << " ";

  InOrder(head->rightchild);

 }

}

 

//后序遍历

void PostOrder(Blink head)

{

 if(head)

 {

  PostOrder(head->leftchild);

  PostOrder(head->rightchild);

  cout << head->data << " ";

 }

}

 

//撤销二叉树

void deleteTree(Blink &head)

{

 if(head)

 {

  deleteTree(head->leftchild);

  deleteTree(head->rightchild);

  delete head;

 }

}

 

//建立二叉排序树

void buildBinarySortTree(Blink &head, int elem[], int length)

{

 Blink p,pre;

 int flagLeftOrRight;    //0表示左孩子,1表示右孩子

 int success;

  

 head = new BTree;   //生成头结点

 head->data = elem[0];  

 head->leftchild = NULL;

 head->rightchild = NULL;

  

 for(int i = 1; i < length; ++i)

 {

  success = 0;

  pre = NULL;

  p = head;

  while(p)    //寻找插入的位置

  {

   pre = p;

   if(p->data == elem[i]) //查找成功

   {

    success = 1;

    break;

   }

   else if(p->data < elem[i]) //沿右孩子搜索

   {

    p = p->rightchild;

    flagLeftOrRight = 1;

   }

   else    //沿左孩子搜索

   {

    p = p->leftchild;

  flagLeftOrRight = 0;

   }

  }

   

  if(!success)

  {

   p = new BTree;     //生成新结点

   p->data = elem[i];

   p->leftchild = NULL;

   p->rightchild = NULL;

    

   if(flagLeftOrRight == 0)  //新插入的结点作为左孩子

   {

    pre->leftchild = p;

   }

   else if(flagLeftOrRight == 1) //新插入的结点作为右孩子

   {

    pre->rightchild = p;

   }

  }

 }

}

 

int main()

{

 int N;

 int elem[110];

 Blink head;

  

  

 while(cin >> N)

 {

  for(int i = 0; i < N; ++i)

  {

   cin >> elem[i];

  }

   

 buildBinarySortTree(head,elem,N); 

   

  PreOrder(head);

  cout << endl;

  InOrder(head);

  cout << endl;

  PostOrder(head);

  cout << endl;

 }

 return 0;

}

37、 题目描述:

判断两序列是否为同1二叉搜索树序列

输入:

开始1个数n(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。

接下去1行是1个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出1颗二叉搜索树。

接下去的n行有n个序列,每个序列格式跟第1个序列1样,请判断这两个序列是否能组成同1颗二叉搜索树。

输出:

如果序列相同则输出YES,否则输出NO

样例输入:

2

567432

543267

576342

0

样例输出:

YES

NO

#include<iostream>

using namespace std;

 

int a[1024];

int b[1024];

void createtree(string s,int c[])

{

    int len=slength();

    for(int i=0;i<len;i++)

    {

 int temp=s[i]-'0';

 for(int j=1;j<=1023;)

 {

     if(c[j]==-1)

     {c[j]=temp;break;}

     else if(c[j]>temp)

     j=j*2;

     else

     j=j*2+1;    

 }

    } 

}

 

int main()

{

    int n,i;

    string s;

    string t;

    while(cin>>n&&n)

    {

 for(i=0;i<1024;i++) a[i]=-1;

 cin>>s;

 createtree(s,a);

 while(n--)

 {

     for(i=0;i<1024;i++) b[i]=-1;

     cin>>t;

     createtree(t,b);

     for(i=0;i<1024;i++) 

     if(a[i]!=b[i]) break;

     if(i==1024)

     cout<<"YES"<<endl;

     else

     cout<<"NO"<<endl;    

 }    

    }

    return 0;

}

38、 题目描述:

读入两个小于10000的正整数AB,计算A+B。需要注意的是:如果AB的末尾K(不超过8)位数字相同,请直接输出-1

输入:

测试输入包含若干测试用例,每个测试用例占1行,格式为"A B K",相邻两数字有1个空格间隔。当AB同时为0时输入结束,相应的结果不要输出。

输出:

对每个测试用例输出1行,即A+B的值或者是-1

样例输入:

1 2 1

11 21 1

108 8 2

36 64 3

0 0 1

样例输出:

3

-1

-1

100

#include<iostream>

#include<string>

#include<fstream>

#include<algorithm>

 

using namespace std;

 

void split(int num,int k,char *str)

{

 int i;

 for (i=0;i<k;i++)

 {

  str[i]=num%10;

  num/=10;

 }

 str[i]='\0';

}

int main()

{

 int a,b,k;

 char cha[10],chb[10];

 //fstream cin("1015txt");

 while (cin>>a>>b,a+b)

 {

  cin>>k;

  split(a,k,cha);

  split(b,k,chb);

  string stra(cha);

  string strb(chb);

  if (stra==strb)

  {

    

   cout<<"-1"<<endl;

  }

  else

  {

   cout<<a+b<<endl;

  }

 }

 return 0;

}

39、 题目描述:

守形数是这样1种整数,它的平方的低位部分等于它本身。

比如25的平方是625,低位部分是25,因此251个守形数。

1个程序,判断N是否为守形数。

输入:

输入包括1个整数N2<=N<100

输出:

可能有多组测试数据,对于每组数据,

输出"Yes!”表示N是守形数。

输出"No!”表示N不是守形数。

样例输入:

25

4

样例输出:

Yes!

No!

#include<stdioh>

#include<stdlibh>

#include<stringh>

 

int n, t;

 

int main() {

    while(~scanf("%d", &n)) {

 t = n * n;

 while(n > 0) {

     if((n % 10) != (t % 10)) break;

     n /= 10;

     t /= 10;

 }

 if(!n) puts("Yes!");

 else

     puts("No!");

    }

    return 0;

}

40、 题目描述:

写个算法,对2个小于1000000000的输入,求结果。

特殊乘法举例:123 * 45 = 1*4 +1*5 +2*4 +2*5 +3*4+3*5

输入:

 两个小于1000000000的数

输出:

 输入可能有多组数据,对于每1组数据,输出Input中的两个数按照题目要求的方法进行运算后得到的结果。

样例输入:

123 45

样例输出:

54

#include <iostream>

#include <string>

 

using namespace std;

 

int main()

{

 string str1,str2;

 while(cin>>str1>>str2)

 {

  int sum=0;

  for(int i=0;i<str1size();i++)

   for(int j=0;j<str2size();j++)

   { 

    sum+=(str1[i]-48)*(str2[j]-48);

   }

   cout<<sum<<endl;

 }

 return 0;

}

41、 题目描述:

N1个四位数,它的9倍恰好是其反序数(示例:1234的反序数是4321

N的值

输入:

程序无任何输入数据

输出:

输出题目要求的四位数,如果结果有多组,则每组结果之间以回车隔开

样例输入:

样例输出:

#include <cstdio>

#include <iostream>

using namespace std;

 

// 1个数反转

int GetReverseNum(int a)

{

 int t = 1000;

 int p = 1;

 int ans = 0;

 for (int i=1; i<=4; i++)

 {

  ans += a / t * p;

  a %= t;

  t /= 10;

  p *= 10;

 }

 return ans;

}

 

int main()

{

 for (int i=1000; i<=1111; i++)

 {

  int t = i * 9;

  if (GetReverseNum(i) == t)

  {

   printf("%d\n", i);

  }

 }

 return 0;

}

42、 题目描述:

打印所有不超过n(n<256)的,其平方具有对称性质的数。

11*11=121

输入:

无任何输入数据

输出:

输出具有题目要求的性质的数。如果输出数据不止1组,各组数据之间以回车隔开。

样例输入:

样例输出:

#include<stdioh>

int main()

{

    int n=256,a[5],b,m,c[256],p=0;

    for(int i=0;i<n;i++)

    {

  int flag=0;

  m=0;

  b=i*i;

  while(b!=0)

  {

     a[m++]=b%10;

     b=(b-a[m-1])/10;

  }

  for(int j=0;j<m/2;j++)

     if(a[j]!=a[m-1-j]){ flag=1;   break;} 

  if(flag==0) printf("%d\n",i);

    } 

    return 0;

}

43、 题目描述:

    The digital root of a positive integer is found by summing the digits of the integer、 If the resulting value is a single digit then that digit is the digital root、 If the resulting value contains two or more digits, those digits are summed and the process is repeated、 This is continued as long as necessary to obtain a single digit

    For example, consider the positive integer 24、 Adding the 2 and the 4 yields a value of 6、 Since 6 is a single digit, 6 is the digital root of 24、 Now consider the positive integer 39、 Adding the 3 and the 9 yields 12、 Since 12 is not a single digit, the process must be repeated、 Adding the 1 and the 2 yeilds 3, a single digit and also the digital root of 39

输入:

    The input file will contain a list of positive integers, one per line、 

    The end of the input will be indicated by an integer value of zero

输出:

    For each integer in the input, output its digital root on a separate line of the output

样例输入:

24

39

0

样例输出:

6

3

#include <iostream>

#include <string>

using namespace std;

 

string getRoot(string s){

    int v = 0;

    for(int i=0;i<slength();i++){

 v += s[i] - '0';

    }

    int t = v,tmp;

    string res;

    resresize(0);

    while(t!=0){

 tmp = t%10;

 respush_back('0'+tmp);

 t /= 10;

    }

    if(ressize()==1){

 return res;

    }

    else{

 return getRoot(res);

    }

}

 

int main(int argc,char* argv[]){

    string s;

    while(cin>>s&&s!="0"){

 cout<<getRoot(s)<<endl;

    }

    return 0;

}

44、 题目描述:

输入两个不超过整型定义的非负10进制整数AB(<=231-1),输出A+Bm (1 < m <10)进制数。

输入:

输入格式:测试输入包含若干测试用例。每个测试用例占1行,给出mAB的值。

m0时输入结束。

输出:

输出格式:每个测试用例的输出占1行,输出A+Bm进制数。

样例输入:

8 1300 48

2 1 7

0

样例输出:

2504

1000

#include <iostream>

#include <string>

 

using namespace std;

 

int main()

{

unsigned int m,a,b;

unsigned long int sum;

unsigned int stack[1000];

int top=-1;

while(cin>>m)

{

if(m==0)

return 0;

cin>>a>>b;

sum=a+b;

if(sum==0)

stack[++top]=0;

while(sum!=0)

{

stack[++top]=sum%m;

sum=sum/m;

}

while(top!=-1)

cout<<stack[top--];

cout<<""<<endl;

}

return 1;

}

45、 题目描述:

    求任意两个不同进制非负整数的转换(2进制~16进制),所给整数在long所能表达的范围之内。

    不同进制的表示符号为(01,、、、,9ab,、、、,f)或者(01,、、、,9AB,、、、,F)。

输入:

    输入只有1行,包含三个整数anba表示其后的a进制整数,b表示欲将a进制整数n转换成b进制整数。ab是十进制整数,2 =< ab <= 16

    数据可能存在包含前导零的情况。

输出:

    可能有多组测试数据,对于每组数据,输出包含1行,该行有1个整数为转换后的b进制数。输出时字母符号全部用大写表示,即(01,、、、,9AB,、、、,F)。

样例输入:

15 Aab3 7

样例输出:

210306

#include <iostream>

#include <string>

#include <cmath>

 

using namespace std;

 

int main()

{

 int a,b;

 long n=0;

 string str;

 while(cin>>a&&a>=2&&a<=16)

 {

  cin>>str>>b;

  int size=strsize() 1;

  for(string::iterator i=strbegin();i!=strend();i++)

  {

   if(*i>64&&*i<71)n+=(*i-55)*pow(a,size--);

   else if(*i>96&&*i<103)n+=(*i-87)*pow(a,size--);

   else n+=(*i-48)*pow(a,size--);

  }

  str="";

  char ch='0';int tmp=0;

  if(n!=0)while(n)

  {

   tmp=n%b;

   if(tmp>9)ch=tmp-10+'A';

   else ch=tmp+'0';

   str+=ch;

   n/=b;

  }

  else str="0";

  for(string::iterator j=strend() 1;j>=strbegin();j--)

  cout<<*j;

  cout<<endl;

 }

 return 0;

}

46、 题目描述:

1个长度最多为30位数字的十进制非负整数转换为二进制数输出。

输入:

多组数据,每行为1个长度不超过30位的十进制非负整数。

(注意是10进制数字的个数可能有30个,而非30bits的整数)

输出:

每行输出对应的二进制数。

样例输入:

0

1

3

8

样例输出:

0

1

11

1000

#include <iostream>

#include <cstdio>

#include <cstring>

#include <bitset>

using namespace std;

int main(){

 int i,j,num[40],len,c,tmp,len_res;

 char s[40],res[200];

// freopen("1txt","r",stdin);

// freopen("outtxt","r",stdout);

 while (scanf("%s",s)!=EOF)

 {

  for (len=0;s[len];len++)

  {

   num[len]=s[len]-'0';

  }

  //跳出循环后长度也就出来了

  i=0;

  len_res=0;

  while (i<len)

  {

   res[len_res++]=num[len-1]%2+'0';

   //这里是转化为2进制,只用最后1位来除2余数就可以了,其他高位对除2余数不影响,因为从高位借过1位来总是能被2整除,

   c=0;//借位

   for (j=i;j<len;j++)

   {

    tmp=num[j];

    num[j]=(num[j]+c)/2;

    if (tmp&1)//当这1位是奇数的时候表示不能整除2,要借位了

    {

     c=10;

    }else{

     c=0;

    }

   }

   if (num[i]==0)//可能前几次不为0,再循环

   {

    i++;

   }

  }

  for (i=len_res-1;i>=0;i--)//逆向输出

  {

   printf("%c",res[i]);

  }

  printf("\n");

 }

// fclose(stdout);

// fclose(stdin);

 return 0;

}

47、 题目描述:

输入1个整数,将其转换成八进制数输出。

输入:

输入包括1个整数N(0<=N<=100000)

输出:

可能有多组测试数据,对于每组数据,

输出N的八进制表示数。

样例输入:

7

8

9

样例输出:

7

10

11

#include<stdioh>

#include<stdlibh>

#include<stringh>

 

 

int main()

   int n; 

   while(~scanf("%d",&n))

   { 

  int num[10];

  memset(num,0,sizeof(num));

  int i=0;

  if(n==0)

   printf("0\n");

  else

  {

   while(n)

   {

  num[i++]=n%8;

  n=n/8;

   }

   for(int j=i-1;j>=0;j--)

   if(j==0)printf("%d\n",num[j]);

   else printf("%d",num[j]);

  } 

   } 

   return 0;

}

48、 题目描述:

输入两个正整数,求其最大公约数。

输入:

测试数据有多组,每组输入两个正整数。

输出:

对于每组输入,请输出其最大公约数。

样例输入:

49 14

样例输出:

7

#include <iostream>

#include <fstream>

using namespace std;

int main(){

   // ifstream cin("inputtxt");

 int a,b,temp;

 while(cin>>a>>b)

 {

   while(b>0)

   {

    a=a%b;

    temp=b;

    b=a;

    a=temp;

   }

   cout<<a<<endl;

  }

}

49、 题目描述:

给定两个正整数,计算这两个数的最小公倍数。

输入:

输入包含多组测试数据,每组只有1行,包括两个不大于1000的正整数。

输出:

对于每个测试用例,给出这两个数的最小公倍数,每个实例输出1行。

样例输入:

10 14

样例输出:

70

#include<stdioh>

int gcd(int a,int b )

{

 return b!=0 ? gcd(b,a%b) :a;

}

int main()

{

 int a,b;

 while(scanf("%d%d",&a,&b)!=EOF)

   printf("%d\n",a*b/gcd(a,b));

 return 0;

}题目描述:

The least common multiple (LCM) of a set of positive integers is the smallest positive integer which is divisible by all the numbers in the set、 For example, the LCM of 5, 7 and 15 is 105

输入:

Input will consist of multiple problem instances、 The first line of the input will contain a single integer indicating the number of problem instances、 Each instance will consist of a single line of the form m n1 n2 n3 、、、 nm where m is the number of integers in the set and n1 、、、 nm are the integers、 All integers will be positive and lie within the range of a 32-bit integer

输出:

For each problem instance, output a single line containing the corresponding LCM、 All results will lie in the range of a 32-bit integer

样例输入:

2

3 5 7 15

6 4 10296 936 1287 792 1

样例输出:

105

10296

50

#include "cstdio"

#include "cstring"

  

int gcd(int a,int b){

    if(b==0) return a;

    else return gcd(b,a%b);

}

  

int main(){ 

    int n;

    scanf("%d",&n);

    while(n--){

 int c;

 scanf("%d",&c);

 int tmp,k=0;

 while(c--){

     scanf("%d",&tmp);

     if(k==0) k=tmp;

     else k=k/gcd(k,tmp)*tmp;

 }

 printf("%d\n",k);

    }

    return 0;

}

51、 题目描述:

给定1个数n,要求判断其是否为素数(0,1,负数都是非素数)。

输入:

测试数据有多组,每组输入1个数n

输出:

对于每组输入,若是素数则输出yes,否则输入no

样例输入:

13

样例输出:

Yes

#include <iostream>

#include <cmath>

 

using namespace std;

int N;

 

void solve()

{

 if(N<=1){cout<<"no"<<endl;return;}

 else

 {

  int M =(int)sqrt((double)N);

  for(int i = 2; i<=M; i++)

   if(N%i == 0)

   {

    cout<<"no"<<endl;

    return;

   }

 }

 cout<<"yes"<<endl;

}

 

int main()

{

 

 while(cin>>N)

 {

  solve();

 }

 return 0;

}

52、 题目描述:

输入1个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1

输入:

输入有多组数据。

每组1行,输入n

输出:

输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数(素数之间用空格隔开,最后1个素数后面没有空格),如果没有则输出-1

样例输入:

100

样例输出:

11 31 41 61 71

#include<iostream>

#include<vector>

#include<cmath>

using namespace std;

 

bool IsPrime(int num)

{

 bool flag = true;

 for(int i=2;i<=(int)sqrt((double)num);i++)

  if(num%i==0)

  {

   flag = false;

   break;

  }

  return flag;

}

int main()

{

 int n;

 vector<int> val;

 while(cin>>n)

 {

  if(n<=10)

   cout<<"-1"<<endl;

  else{

   valclear();

   for(int i=11;i<n;i=i+10)

    if(IsPrime(i))

     valpush_back(i);

   for(size_t ind=0;ind<valsize() 1;ind++)

    cout<<val[ind]<<' ';

   cout<<val[valsize() 1]<<endl;

  }

 }

 return 0;

}

53、 题目描述:

Output the k-th prime number

输入:

k10000

输出:

The k-th prime number

样例输入:

3

7

样例输出:

5

17

#include<iostream>

#include<malloch>

#include<stdioh>

using namespace std;

int main()

{

 

int *Isprime;

int i,j,k,m,z;

int N=200000,count;

Isprime=(int*)malloc((N+1)*sizeof(int));

for(int n=0;n!=N;n++)

{

Isprime[n]=1;

}

 

for(i=0;i!=N;i++)

{

if(i%2==0)

{

Isprime[i]=0;

}

}

Isprime[2]=1;

Isprime[1]=0;

for(j=3;j*j<N;j++)

{

if(Isprime[j]==1)

{

for(k=j+1;k<N;k++)

{

if(k!=j&&k%j==0)

{

Isprime[k]=0;

}

}

}

}

 

while(cin>>z)

{

count=0;

for(m=0;m!=N;m++)

{

if(Isprime[m]==1)

{

count++;

if(count==z)

break;

}

}

cout<<m<<endl;

}

return 0;

 

}

54、 题目描述:

Goldbach's Conjecture: For any even number n greater than or equal to 4, there exists at least one pair of prime numbers p1 and p2 such that n = p1 + p2、 

This conjecture has not been proved nor refused yet、 No one is sure whether this conjecture actually holds、 However, one can find such a pair of prime numbers, if any, for a given even number、 The problem here is to write a program that reports the number of all the pairs of prime numbers satisfying the condition in the conjecture for a given even number

A sequence of even numbers is given as input、 Corresponding to each number, the program should output the number of pairs mentioned above、 Notice that we are interested in the number of essentially different pairs and therefore you should not count (p1, p2) and (p2, p1) separately as two different pairs

输入:

An integer is given in each input line、 You may assume that each integer is even, and is greater than or equal to 4 and less than 2^15、 The end of the input is indicated by a number 0

输出:

Each output line should contain an integer number、 No other characters should appear in the output

样例输入:

6

10

12

0

样例输出:

1

2

1

#include <stdioh>

#include <mathh>

 

bool mark[33001];

 

void init()

{

    for( int i = 2; i <= 32770; i ++ ) 

 mark[i] = false;

    for( int i = 2; i <= 32770; i ++ ) {

 if( !mark[i] ) {

     for( int j = i * i; j <= 32770; j += i )

  mark[j] = true;

 }

    }   

}

 

int main()

{

    init();

    int n;

    while (scanf("%d", &n) != EOF && n != 0 ) {

 int cnt = 0;

 for( int i = 2; i <= n / 2; i ++ ) 

     if( !mark[i] && !mark[n - i] )

  cnt ++ ;

 printf("%d\n", cnt);

    }

    return 0;

}

55、题目描述:

求正整数N(N>1)的质因数的个数。

相同的质因数需要重复计算。如120=2*2*2*3*5,共有5个质因数。

输入:

可能有多组测试数据,每组测试数据的输入是1个正整数N(1<N<10^9)

输出:

对于每组数据,输出N的质因数的个数。

样例输入:

120

样例输出:

5

#include <iostream>

#include <cstdio>

#include <string>

#include <cstring>

#include <cctype>

#include <cstdlib>

#include <stringh>

#include <algorithm>

#include <cmath>

using namespace std;

 

int main()

{

    int n,ans,i;

    while(scanf("%d",&n) == 1)

    {

    ans = 0;

    for(i = 2;i <= sqrt(n);i++)

      if(n % i == 0)

      {

        while(n%i == 0)

        {

       ans ++;

       n = n / i;

        }

      }

    if(n > 1)

     ans ++;

    printf("%d\n",ans);

    }

    return 0;

}

56、 题目描述:

给定na求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。

输入:

两个整数n(2<=n<=1000)a(2<=a<=1000)

输出:

1个整数、

样例输入:

6 10

样例输出:

1

#include <iostream>

using namespace std;

 

#define MAXSIZE 500

 

int main() {

 int n, a;

 while(cin >> n && cin >> a){

  int minDivisor[MAXSIZE];

  int countMinDiv[MAXSIZE];

  int countDiv = 0;

 

  int temA = a;

  for(int i = 2; i<=temA; i++){

   if(temA%i == 0){

    minDivisor[countDiv] = i;

    countMinDiv[countDiv] = 0;

    while(temA%i == 0){

     temA /= i;

     countMinDiv[countDiv]++;

    }

    countDiv++;

   }

  }

 

  int k = 0, count = 0;

 

  for(int j=0; j<countDiv; j++){

   count = 0;

   for(int i=2; i<=n; i++){

    int tem = i;

    while(tem%minDivisor[j] == 0){

     count++;

     tem /= minDivisor[j];

    }

   }

   countMinDiv[j] = count/countMinDiv[j];

  }

 

  k = countMinDiv[0];

  for(int i=1; i<countDiv; i++){

   if(countMinDiv[i] < k){

    k = countMinDiv[i];

   }

  }

 

  cout << k <<endl;

 }

 return 0;

}

57、 题目描述:

输入n个整数,依次输出每个数的约数的个数

输入:

输入的第1行为N,即数组的个数(N<=1000)

接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)

N=0时输入结束。

输出:

可能有多组输入数据,对于每组输入数据,

输出N行,其中每1行对应上面的1个数的约数的个数。

样例输入:

5

1 3 4 6 12

样例输出:

1

2

3

4

6

#include <iostream>

#include <cstdio>

#include <cmath>

using namespace std;

 

const int MAX = 1000 + 5;

int a[MAX];

 

int main()

{

 int n, m;

 int i, j;

 while (scanf("%d", &n) != EOF)

 {

  for (j=0; j<n; j++)

  {

   scanf("%d", &m);

   int ans = 0;

   int t = sqrt(m * 10);

   for (i=1; i<=t; i++)

   {

    if (m % i == 0)

    {

     (m / i == i)? ans++ : ans += 2;

    }

   }

   printf("%d\n", ans);

  }

 }

 return 0;

}

58、 题目描述:

A^B的最后三位数表示的整数。说明:A^B的含义是“AB次方”

输入:

输入数据包含多个测试实例,每个实例占1行,由两个正整数AB组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。

输出:

对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占1行。

样例输入:

2 3

12 6

6789 10000

0 0

样例输出:

8

984

1

#include <stdioh>

int main()

{

    int a,b;

    while(scanf("%d%d",&a,&b)!=EOF){

 if(a==0&&b==0) break;

 int ans=1;

 while(b!=0){

     if(b%2==1){

  ans*=a;

  ans%=1000;

     }

     b/=2;

     a*=a;

     a%=1000;

 }

 printf("%d\n",ans);

    }

    return 0;

}

59、 题目描述:

Xinlv wrote some sequences on the paper a long time ago, they might be arithmetic or geometric sequences、 The numbers are not very clear now, and only the first three numbers of each sequence are recognizable、 Xinlv wants to know some numbers in these sequences, and he needs your help

输入:

The first line contains an integer N, indicting that there are N sequences、 Each of the following N lines contain four integers、 The first three indicating the first three numbers of the sequence, and the last one is K, indicating that we want to know the K-th numbers of the sequence

You can assume 0 < K <= 10^9, and the other three numbers are in the range [0, 2^63)、 All the numbers of the sequences are integers、 And the sequences are non-decreasing

输出:

Output one line for each test case, that is, the K-th number module (%) 200907

样例输入:

2

1 2 3 5

1 2 4 5

样例输出:

5

16

#include <stdioh>

 

int main()

{

    int n;

    while(scanf("%d",&n)!=EOF)

    {

    for(int i=0;i<n;i++)

    {

 long long a,b,c,k,ans;

 scanf("%lld%lld%lld%lld",&a,&b,&c,&k);

 if(a+c==b*2)

 {

     ans=a+(c-b)*(k-1);

     ans%=200907;

 }else{

     long long tmp=(b/a)%200907;

     ans=a%200907;

     k=k-1;

     while(k!=0)

     {

  if(k%2==1)

  {

      ans*=tmp;

      ans%=200907;

  }

  k/=2;

  tmp*=tmp;

  tmp%=200907;

     }

 }

 printf("%lld\n",ans);

    }

    }

    return 0;

}

60、 题目描述:

A1个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973

输入:

数据的第1行是1T,表示有T组数据。

每组数据的第1行有n(2 <= n <= 10)k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。

输出:

对应每组数据,输出Tr(A^k)%9973

样例输入:

2

2 2

1 0

0 1

3 99999999

1 2 3

4 5 6

7 8 9

样例输出:

2

2686

#include<stdioh>

int a[11][11],ans[11][11];

void f(int a[11][11],int b[11][11],int n){

    int i,j,k,c[11][11];

    for(i=0;i<n;i++)

 for(j=0;j<n;j++)c[i][j]=0;

    for(i=0;i<n;i++)

 for(j=0;j<n;j++){

    for(k=0;k<n;k++)c[i][j]=(c[i][j]%9973+a[i][k]*b[k][j]%9973)%9973;

 }

    for(i=0;i<n;i++)

 for(j=0;j<n;j++)a[i][j]=c[i][j];

 

}

int main(){

    int t,n,k,i,j,sum;

    while(scanf("%d",&t)!=EOF){

 while(t--!=0){

     scanf("%d%d",&n,&k);

     for(i=0;i<n;i++)

  for(j=0;j<n;j++){

      scanf("%d",&a[i][j]);

      ans[i][j]=0;

      if(i==j)

      ans[i][j]=1;

  }

 

     while(k){

  int x=k%2;

  if(x==1){

      f(ans,a,n);

 

  }

  f(a,a,n);

  k/=2;

     }

     for(i=0,sum=0;i<n;i++){

  sum=(sum%9973+ans[i][i]%9973)%9973;

     }

     printf("%d\n",sum);

 }

    }

    return 0;

}

61、 题目描述:

实现1个加法器,使其能够输出a+b的值。

输入:

输入包括两个数ab,其中ab的位数不超过1000位。

输出:

可能有多组测试数据,对于每组数据,

输出a+b的值。

样例输入:

2 6

10000000000000000000 10000000000000000000000000000000

样例输出:

8

10000000000010000000000000000000

#include <stdioh>

#include <stringh>

#define MAXN 1000+10

 

char a[MAXN];

char b[MAXN];

 

int main(){

 int n,m,i,s;

   while(scanf("%s%s",a,b)==2){

  

 

    int c[MAXN]={0};

    int d[MAXN]={0};

    int sum[MAXN]={0};

// printf("%s %s\n",a,b);

 n=strlen(a);

 m=strlen(b);

  int cin =0;

   

 for(i=0;i<n;i++){

   

 c[n-i-1]=a[i]-'0';

 }

 for(i=0;i<m;i++){

 d[m-i-1]=b[i]-'0';

 }

 

 for(i=0;i<MAXN;i++){

  s=c[i]+d[i]+cin;

  sum[i]=s%10;

  cin=s/10;

   }

   

 

 for(i=MAXN-1;i>=0;i--){

  if(i!=0){

  if(!(sum[i]==0))

  { 

      

  int j;

  for(j=i;j>=0;j--)

  {

   printf("%d",sum[j]);  

  }

  i=-1;

 

   

  }

  }

  else{

     if(sum[i]==0) printf("0");

     else printf("%d",sum[0]);

  }

 

  

 }

  printf("\n");

 }

return 0;

}

63、 题目描述:

 输入1个正整数N,输出N的阶乘。

输入:

正整数N(0<=N<=1000)

输出:

 输入可能包括多组数据,对于每1组输入数据,输出N的阶乘

样例输入:

4

5

15

样例输出:

24

120

1307674368000

#include "cstdio"

#include "cstring"

#include "cstdlib"

 

int res[10010];

 

int main()

{

    int n;

    while (scanf("%d", &n) == 1)

    {

 int i, j;

 memset(res, 0, sizeof(res));

 res[0] = 1;

 res[1] = 1;

 for (i = 2; i <= n; i++)

 {

     for (j = 1; j <= res[0]; j++)

  res[j] = res[j] * i;

  

     for (j = 1; j <= res[0]; j++)

     {

  if (res[j] >= 10)

  {

      res[j+1] += res[j] / 10;

      res[j] %= 10;

      if (j == res[0])

   res[0]++;

  }

     }

 }

 for (i = res[0]; i >= 1; i--)

     printf("%d", res[i]);

 printf("\n");

    }

    return 0;

}

64、 题目描述:

M进制的数X转换为N进制的数输出。

输入:

输入的第1行包括两个整数:MN(2<=M,N<=36)

下面的1行输入1个数XXM进制的数,现在要求你将M进制的数X转换成N进制的数输出。

输出:

输出XN进制表示的数。

样例输入:

16 10

F

样例输出:

15

提示:

输入时字母部分为大写,输出时为小写,并且有大数据。

来源:

#include<iostream>

#include<stringh>

#include<string>

#include<ctypeh>

#include<mathh>

#include<algorithm>

#include<cstdio>

using namespace std;

int M,N;

char a[10000];

string quotient_handle(const string& s1 )

{

 string temp="";

 string::size_type index=s1find_first_not_of('0');

 if(index==string::npos)

  ;

 else

  tempassign(s1,index,s1length() index);

 return temp;

}

 

int main()

{

 while(scanf("%d %d %s",&M,&N,&a)!=EOF)

 {

  string quotient="";;

  string div(a);

  int temp=0; 

  while(div!="")

  {

   string div_temp="";

   for(int i=0,index=0;i<divlength();i++)

   {

    int digit_temp=0;

    if(isdigit(div[i]))

     digit_temp=(div[i]-'0')+(temp*M);

    else

     digit_temp=(div[i]-'A'+10)+(temp*M);

    div_temp+=(digit_temp/N)<10? digit_temp/N+'0': digit_temp/N-10+'A';

    temp=digit_temp%N;

   }

   quotient+=(temp)<10? temp+'0' : temp-10+'a';

   div=quotient_handle(div_temp);

   temp=0;

  }

  reverse(quotientbegin(),quotientend());

  cout<<quotient<<endl;

 

 }

 return 0;

}

65、 题目描述:

2个浮点数相加的和

题目中输入输出中出现浮点数都有如下的形式:

P1P2、、、PiQ1Q2、、、Qj

对于整数部分,P1P2、、、Pi1个非负整数

对于小数部分,Qj不等于0

输入:

对于每组案例,第1行是测试数据的组数n,每组测试数据占2行,分别是两个加数。

每组测试数据之间有1个空行,每行数据不超过100个字符

输出:

每组案例是n行,每组测试数据有1行输出是相应的和。

输出保证1定是1个小数部分不为0的浮点数

样例输入:

2

0111111111111111111111111111111

0111111111111111111111111111111

10000000655555555555555555555555555555

1444444444444444444444444444445

样例输出:

0222222222222222222222222222222

100000021

#include <iostream>

#include <stringh>

using namespace std;

 

 

char addOne137[1000];

char addTwo137[1000];

char result137[1000];

 

 

int doubleAdd137()

{

int len1 = strlen( addOne137 );

int len2 = strlen( addTwo137 );

 

//if ( len1 == len2 && len1 == 3 )

//{

// if ( addOne137[0] == '0' && addTwo137[0] =='0' && addOne137[2] == '0' && addTwo137[2] == '0')

// {

// //strcpy(result137,addOne137);

// result137[0] = '0';

// result137[1] = '\0';

// return 3;

// }

//}

 

int point1 = 0;

while( addOne137[point1] != '')

point1++;

int point2 = 0;

while( addTwo137[point2] != '')

point2++;

 

int i = len1 -1;

int j = len2 -1;

 

int pos = 0;

while( i - point1 > j - point2)

result137[pos++] = addOne137[i--];

while( j - point2 > i - point1)

result137[pos++] = addTwo137[j--];

 

int d = 0;

int cur;

int point;

while ( i>=0 && j>=0 )

{

if ( addOne137[i] == '')

{

i--;

j--;

point = pos;

result137[pos++] = '';

continue;

}

cur = addOne137[i--] + addTwo137[j--] -'0' -'0' + d;

result137[pos++] = cur % 10 + '0';

d = cur / 10;

}

 

while ( i>=0 )

{

cur = addOne137[i--] - '0' + d;

result137[pos++] = cur % 10 + '0';

d = cur / 10;

}

 

while ( j >= 0 )

{

cur = addTwo137[j--] - '0' + d;

result137[pos++] = cur % 10 + '0';

d = cur / 10;

}

 

while ( d > 0 )

{

result137[pos++] = d % 10 + '0';

d = d / 10;

}

result137[pos] = '\0';

 

int start = 0;;

while( start < point -1 && result137[start] == '0')

{

start ++;

pos--;

}

 

strcpy(result137,result137+start);

for ( int i=0; i< pos/2; i++)

{

char c = result137[i];

result137[i] = result137[pos-1-i] ;

result137[pos-1-i] = c;

}

 

return pos;

 

}

 

int main()

{

int n;

cin >> n;

while ( n-- )

{

cin >> addOne137 >> addTwo137;

doubleAdd137();

cout << result137 << endl;

}

return 0;

}

66、 题目描述:

N个长度最长可达到1000的数进行排序。

输入:

输入第1行为1个整数N(1<=N<=100)

接下来的N行每行有1个数,数的长度范围为1<=len<=1000

每个数都是1个正数,并且保证不包含前缀零。

输出:

可能有多组测试数据,对于每组数据,将给出的N个数从小到大进行排序,输出排序后的结果,每个数占1行。

样例输入:

3

11111111111111111111111111111

2222222222222222222222222222222222

33333333

样例输出:

33333333

11111111111111111111111111111

2222222222222222222222222222222222

#include<stdioh>

#include<stdlibh>

#include<stringh>

#include<algorithm>

using namespace std;

 

struct cha{

   char num[1010];

   };

bool cmp(struct cha cha1,struct cha cha2){

 if(strlen(cha1num)==strlen(cha2num))//WA*1,设计比较算法的时候误将两个string数组strcmp比较是否  

 

      //相等作为边界条件

     return strcmp(cha1num,cha2num)<0;

 else

     return strlen(cha1num)<strlen(cha2num);

 }

 

int main()

{

  int n;

  while(~scanf("%d",&n))

  {

   struct cha cha1[n];

   for(int i=0;i<=n-1;i++)

  scanf("%s",&cha1[i]num);

   

   sort(cha1,cha1+n,cmp);

   for(int i=0;i<=n-1;i++)

  printf("%s\n",cha1[i]num);

    

  } 

  

 return 0; 

}

67、 题目描述:

    对于1个十进制数A,将A转换为二进制数,然后按位逆序排列,再转换为十进制数B,我们乘BA的二进制逆序数。

    示例对于十进制数173,它的二进制形式为10101101,逆序排列得到10110101,其十进制数为181181即为173的二进制逆序数。

输入:

    11000(10^999)以内的十进制数。

输出:

    输入的十进制数的二进制逆序数。

样例输入:

173

样例输出:

181

#include<stdioh>

#include<stringh>

int main()

{

 int a[1000],b[100000],c[1500],temp[1500],i,j,l,sum,remain,len,flag;//a为原数组,b为二进制,c为转换后,temp为幂次临时数组

 char cccc[1000];

 while(scanf("%s",cccc)!=EOF){memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));memset(temp,0,sizeof(temp));

 l=strlen(cccc);

 for(i=0;i<l;i++)

  a[i]=cccc[i]-'0';

 if(l==1&&a[0]==0){printf("0\n");continue;}

 sum=1;

 len=0;//记录二进制数的位数#3##

 while(sum>0)//计算二进制数

 {

   

  remain=0;//记录除2的余数

  for(i=0;i<l;i++)

  {

   a[i]+=remain*10;

   remain=a[i]%2;

   a[i]=a[i]/2;

  }

  b[len]=remain;

  len++;

  for(i=0,sum=0;i<l;i++)

   sum+=a[i];

 }

 temp[0]=1;

 for(i=len-1;i>=0;i--)

 { 

  if(b[i])//若该二次项为则相加,否则不加

  {

   for(j=0;j<1500;j++)

    c[j]+=temp[j]; 

   for(j=0;j<1499;j++)

   {

    c[j+1]+=c[j]/10;

    c[j]=c[j]%10;

   }

  }

 for(j=0;j<1499;j++)

   temp[j]=temp[j]*2;

   for(j=0;j<1499;j++)

   {

    temp[j+1]+=temp[j]/10;

    temp[j]=temp[j]%10;

   }

 } 

 flag=0;

 for(j=1499;j>=0;j--)

 {

  if(flag==1)

   printf("%d",c[j]);

  else if(c[j]>0)

  {

   flag=1;

   printf("%d",c[j]);

  }

 }

 printf("\n");

 }

 return 1;

}

68、 题目描述:

    某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不1定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?

输入:

    测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出1对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1N编号。 

    注意:两个城市之间可以有多条道路相通,也就是说

    3 3

    1 2

    1 2

    2 1

    这种输入也是合法的

    当N0时,输入结束,该用例不被处理。

输出:

    对每个测试用例,在1行里输出最少还需要建设的道路数目。

样例输入:

4 2

1 3

4 3

3 3

1 2

1 3

2 3

5 2

1 2

3 5

999 0

0

样例输出:

1

0

2

998

#include<iostream>

#include<algorithm>

#include<cstring>

#include<cstdio>

#include<cstdlib>

using namespace std;

int fa[1000];

int getfa(int i)

{

if(fa[i]==i)

  return i;

else

fa[i]=getfa(fa[i]);

return fa[i];

}

int main()

{

int n,m;

int i,j;

int road;

int a,b;

while(cin>>n&&n)

{

  for(int i=1;i<=n;i++)

   fa[i]=i;

  cin>>m;

  while(m--)

  {

   cin>>a>>b;

   fa[getfa(b)]=getfa(a);

  }

  road=0;

  for(i=1;i<=n;i++)

  {

   for(j=1;j<=n;j++)

   {

    if(getfa(i)!=getfa(j))

    {

 fa[getfa(j)]=getfa(i);

 road++;

    }

   }

  }

  cout<<road<<endl;

}

return 0;

}

67、 题目描述:

Mr Wang wants some boys to help him with a project、 Because the project is rather complex, the more boys come, the better it will be、 Of course there are certain requirementsMr Wang selected a room big enough to hold the boys、 The boy who are not been chosen has to leave the room immediately、 There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning、 After Mr Wang's selection any two of them who are still in this room should be friends (direct or indirect), or there is only one boy left、 Given all the direct friend-pairs, you should decide the best way

输入:

The first line of the input contains an integer n (0 ≤ ≤ 100 000) - the number of direct friend-pairs、 The following n lines each contains a pair of numbers A and B separated by a single space that suggests A and B are direct friends、 (A ≠ B, 1 ≤ A, B ≤ 10000000)

输出:

The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep

样例输入:

4

1 2

3 4

5 6

1 6

4

1 2

3 4

5 6

7 8

样例输出:

4

2

#include <cstdio>

#include <cstring>

#include <vector>

#include <list>

#include <queue>

using namespace std;

 

const int MAX_SIZE=10000000;

//vector<int> edges[MAX_SIZE];

int cc[MAX_SIZE];

int cc_cnt;

 

int ufs_root(int n)

{

    //while(cc[n]>=0)    n=cc[n];

    //return n;

    if(cc[n]<0)  return n;

    else    return cc[n]=ufs_root(cc[n]);//路径压缩

}

int main_union()

{

    int n,m;

    while(scanf("%d",&m)>0)

    {

 int i,j;

  

 n=MAX_SIZE;

 memset(cc,-1,n*sizeof(int));

 int max_cc=1;

 int src,dst;

 for(i=0;i<m;i++)

 {

     scanf("%d%d",&src,&dst);

     src--;

     dst--;

  

     src=ufs_root(src);

     dst=ufs_root(dst);

     if(src!=dst)

     {

  /*

  if(cc[src]>cc[dst])  cc[src]=dst;

  else if(cc[src]<cc[dst]) cc[dst]=src;

  else

  {

      cc[src]=dst;

      cc[dst]--;

  }*/

  if(cc[src]>=cc[dst])

  {

      cc[dst]+=cc[src];

      cc[src]=dst;

      if(-cc[dst]>max_cc)  max_cc=-cc[dst];

  }

  else

  {

      cc[src]+=cc[dst];

      cc[dst]=src;

      if(-cc[src]>max_cc)  max_cc=-cc[src];

  }

     }

 }

  

 printf("%d\n",max_cc);

    }

    return 0;

}

 

int main()

{

    //main_bfs();

    //main_dfs();

    main_union();

    return 0;

}

69、 题目描述:

    给定1个无向图和其中的所有边,判断这个图是否所有顶点都是连通的。

输入:

    每组数据的第1行是两个整数 和 m0<=n<=1000)。表示图的顶点数目,表示图中边的数目。如果 为 表示输入结束。随后有 行数据,每行有两个值 和 y0<x, y <=n),表示顶点 和 相连,顶点的编号从 开始计算。输入不保证这些边是否重复。

输出:

    对于每组输入数据,如果所有顶点都是连通的,输出"YES",否则输出"NO"

样例输入:

4 3

1 2

2 3

3 2

3 2

1 2

2 3

0 0

样例输出:

NO

YES

#include <memoryh>

#include <iostream>

#include <queue>

using namespace std;

#define N 1004

bool t[N][N], v[N]; //v=visited

bool BFS( int &n ){

 memset(v,0,sizeof(v));

 int i, j, count=1;

 queue<int> q;

 qpush(1); v[1] = 1; //1个元素入队

 while( !qempty() ){

  i = qfront(); qpop(); //队首出队 其邻接点入队

  for( j=1; j<=n; j++ )

   if( t[i][j] && !v[j] )

    { v[j]=1; count++; qpush(j); }

 }

 if( count == n ) return 1;

 else return 0;

}

int main()

{

 int i, j, k, n, m;

 int a, b;

 while( cin >> n >> m && n ){

  for( i=1; i<=n; i++ )

   for( j=1; j<=n; j++ )

    t[i][j] = 0;

  for( i=0; i<m; i++ ){

   cin >> a >> b;

   t[a][b] = t[b][a] = 1;

  }

  if( n == 1 )

   cout << "YES\n";

  else if( m < n-1 || !BFS(n) )

   cout << "NO\n";

  else cout << "YES\n";

 }

 return 0;

}

70、 题目描述:

Today is Ignatius' birthday、 He invites a lot of friends、 Now it's dinner time、 Ignatius wants to know how many tables he needs at least、 You have to notice that not all the friends know each other, and all the friends do not want to stay with strangers

One important rule for this problem is that if I tell you A knows B, and B knows C, that means A, B, C know each other, so they can stay in one table

For example: If I tell you A knows B, B knows C, and D knows E, so A, B, C can stay in one table, and D, E have to stay in the other one、 So Ignatius needs 2 tables at least

输入:

The input starts with an integer T(1<=T<=25) which indicate the number of test cases、 Then T test cases follow、 Each test case starts with two integers N and M(1<=N,M<=1000)、 N indicates the number of friends, the friends are marked from 1 to N、 Then M lines follow、 Each line consists of two integers A and B(A!=B), that means friend A and friend B know each other、 There will be a blank line between two cases

输出:

For each test case, just output how many tables Ignatius needs at least、 Do NOT print any blanks

样例输入:

2

5 3

1 2

2 3

4 5

5 1

2 5

样例输出:

2

4

#include<cstdio>

#define N 1010

int tree[N];

 

int getRoot(int x){

    if(tree[x]==-1) return x;

    else{

 int tmp=getRoot(tree[x]);

 tree[x]=tmp;

 return tmp;

    }

}

 

int main(){

    int t;

    scanf("%d",&t);

    while(t--){

 int n,m;

 scanf("%d%d",&n,&m);

 for(int i=1;i<=n;i++) tree[i]=-1;

 while(m--){

     int a,b;

     scanf("%d%d",&a,&b);

     a=getRoot(a);b=getRoot(b);

     if(a!=b) tree[b]=a;

 }

 int count=0;

 for(int i=1;i<=n;i++){

     if(tree[i]==-1) count++;

 }

 printf("%d\n",count);

    }

    return 0;

}

71、 题目描述:

One way that the police finds the head of a gang is to check people's phone calls、 If there is a phone call between A and B, we say that A and B is related、 The weight of a relation is defined to be the total time length of all the phone calls made between the two persons、 A "Gang" is a cluster of more than 2 persons who are related to each other with total relation weight being greater than a given threthold K、 In each gang, the one with maximum total weight is the head、 Now given a list of phone calls, you are supposed to find the gangs and the heads

输入:

For each case, the first line contains two positive numbers N and K (both less than or equal to 1000), the number of phone calls and the weight threthold, respectively、 Then N lines follow, each in the following format:

Name1 Name2 Time

where Name1 and Name2 are the names of people at the two ends of the call, and Time is the length of the call、 A name is a string of three capital letters chosen from A-Z、 A time length is a positive integer which is no more than 1000 minutes

输出:

For each test case, first print in a line the total number of gangs、 Then for each gang, print in a line the name of the head and the total number of the members、 It is guaranteed that the head is unique for each gang、 The output must be sorted according to the alphabetical order of the names of the heads

样例输入:

8 59

AAA BBB 10

BBB AAA 20

AAA CCC 40

DDD EEE 5

EEE DDD 70

FFF GGG 30

GGG HHH 20

HHH FFF 10

8 70

AAA BBB 10

BBB AAA 20

AAA CCC 40

DDD EEE 5

EEE DDD 70

FFF GGG 30

GGG HHH 20

HHH FFF 10

样例输出:

2

AAA 3

GGG 3

0

#include <cstdio>

#include <cstring>

#include <vector>

#include <list>

#include <queue>

#include <algorithm>

using namespace std;

 

const int MAX_SIZE=1000+1;

//vector<int> edges[MAX_SIZE];

int cc[MAX_SIZE];

int cc_cnt;

 

const int MAX_NAME_LEN=3+1;

char name[MAX_SIZE][MAX_NAME_LEN];

int node_cnt;

int cc_weight[MAX_SIZE],max_node[MAX_SIZE],node_weight[MAX_SIZE];

class CompHeadName

{

public:

    bool operator()(int n1,int n2)  {return strcmp(name[max_node[n1]],name[max_node[n2]])<0;}

};

 

int ufs_root(int n)

{

    //while(cc[n]>=0)    n=cc[n];

    //return n;

    if(cc[n]<0)  return n;

    else    return cc[n]=ufs_root(cc[n]);//路径压缩

}

int main_union()

{

    int n,m,k;

    while(scanf("%d%d",&m,&k)>0)

    {

 int i,j,t;

  

 n=MAX_SIZE;

 memset(cc,-1,n*sizeof(int));

 memset(cc_weight,0,n*sizeof(int));

 memset(max_node,-1,n*sizeof(int));

 memset(node_weight,0,n*sizeof(int));

 char sname[MAX_NAME_LEN],dname[MAX_NAME_LEN];

 node_cnt=0;

 int src,dst,weight;

 int rs,rd;

 for(i=0;i<m;i++)

 {

     scanf("%s%s%d",sname,dname,&weight);

     for(src=0;src<node_cnt;src++)

  if(strcmp(sname,name[src])==0)  break;

     if(src==node_cnt)   strcpy(name[node_cnt++],sname);

     for(dst=0;dst<node_cnt;dst++)

  if(strcmp(dname,name[dst])==0)  break;

     if(dst==node_cnt)   strcpy(name[node_cnt++],dname);

  

     node_weight[src]+=weight;

     node_weight[dst]+=weight;

  

     rs=ufs_root(src);

     rd=ufs_root(dst);

     if(rs!=rd)

     {

  if(cc[rs]>=cc[rd])

  {

      t=rd;

      rd=rs;

      rs=t;

  }

  cc[rs]+=cc[rd];

  cc[rd]=rs;

  cc_weight[rs]+=cc_weight[rd];

  if(max_node[rs]<0 || node_weight[max_node[rd]]>node_weight[max_node[rs]]) max_node[rs]=max_node[rd];

     }

     cc_weight[rs]+=weight;

     if(max_node[rs]<0 || node_weight[src]>node_weight[max_node[rs]])  max_node[rs]=src;

     if(node_weight[dst]>node_weight[max_node[rs]])   max_node[rs]=dst;

 }

  

 int gang_cnt=0;

 int gangs[MAX_SIZE];

 for(i=0;i<n;i++)

 {

     if(cc[i]>=0) continue;

     if(-cc[i]>2 && cc_weight[i]>k)    gangs[gang_cnt++]=i;

 }

 sort(gangs,gangs+gang_cnt,CompHeadName());

  

 printf("%d\n",gang_cnt);

 for(i=0;i<gang_cnt;i++)

 {

     printf("%s %d\n",name[max_node[gangs[i]]],-cc[gangs[i]]);

 }

    }

    return 0;

}

 

int main()

{

    //main_bfs();

    //main_dfs();

    main_union();

    return 0;

}

72、 题目描述:

    某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不1定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。

输入:

    测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出1对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1N编号。

    当N0时,输入结束,该用例不被处理。

输出:

    对每个测试用例,在1行里输出最小的公路总长度。

样例输入:

3

1 2 1

1 3 2

2 3 4

4

1 2 1

1 3 4

1 4 1

2 3 3

2 4 2

3 4 5

0

样例输出:

3

5

#include <stdioh>

#include <stdlibh>

#include <stringh>

#define N 100

#define MAX 1000000

typedef struct{

 int fromvex,endvex;

 int length;

}edge;

int dist[N][N];

void prim(int n){

 edge T[n - 1];

 int i,k,min,j,m,v,d;

 int sum = 0;

 edge e;

 for(i = 1;i < n;i ++){

  T[i - 1]fromvex = 1;

  T[i - 1]endvex = i + 1;

  T[i - 1]length = dist[0][i];

 }

 for(k = 0;k < n-1;k ++){

  min = MAX;

  for(j = k;j < n -1;j ++){

   if(T[j]length < min){

    min = T[j]length;

    m = j;

   }

  }

  sum += T[m]length;

  e = T[m];

  T[m] = T[k];

  T[k] = e;

  v = T[k]endvex;

  for(j = k + 1;j < n-1;j ++){

   d  = dist[v - 1][T[j]endvex- 1];

   if(d < T[j]length){

    T[j]length = d;

    T[j]fromvex = v;

   }

  }

 }

 printf("%d\n",sum);

}

int main(){

 int n,i;

 int from,end,value;

 while(scanf("%d",&n) != EOF){

  if(n == 0)  return 0;

  memset(dist,MAX,n * n * sizeof (int));

  int num = n *(n - 1)/2;

  for(i = 0;i < num;i ++){

   scanf("%d %d %d",&from,&end,&value);

   dist[from - 1][end - 1] = value;

   dist[end - 1][from - 1] = value;

  }

  prim(n);

 }

}

73、 题目描述:

    In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad's back to form a picture of the Liberty Bell、 Alas, one of the freckles turns out to be a scar, so his Ripley's engagement falls through、 

    Consider Dick's back to be a plane with freckles at various (x,y) locations、 Your job is to tell Richie how to connect the dots so as to minimize the amount of ink used、 Richie connects the dots by drawing straight lines between pairs, possibly lifting the pen between lines、 When Richie is done there must be a sequence of connected lines from any freckle to any other freckle、 

输入:

    The first line contains 0 < n <= 100, the number of freckles on Dick's back、 For each freckle, a line follows; each following line contains two real numbers indicating the (x,y) coordinates of the freckle

输出:

    Your program prints a single real number to two decimal places: the minimum total length of ink lines that can connect all the freckles

样例输入:

3

10 10

20 20

20 40

样例输出:

341

#include<stdioh>

#include<stringh>

#include<mathh>

#define INF 0x7fffffff

double dis[101][101],sum,x[101],y[101];

int flag[101]={0};

int visitedcount();

double prim();

int i,j,n,count,newx,newy,dist;

int main()

{

 //freopen("inputtxt","r",stdin);

 while(~scanf("%d",&n)&&n!=0)

 {

  memset(dis,0,sizeof(dis));    //要加stringh头文件

  memset(flag,0,sizeof(flag));

  for(i=1;i<=n;i++)

   scanf("%lf %lf",&x[i],&y[i]);

  for(i=1;i<=n;i++)

   for(j=i+1;j<=n;j++)

   {

    dis[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));

    dis[j][i]=dis[i][j];

   }

  double out=prim();

  printf("%2f\n",out);

 }

 return 0;

}

double prim()    //prim算法构造最小生成树

{

 flag[1]=1;

 sum=0;

 while(visitedcount()<n)

 {

  double min=INF;

  for(i=1;i<=n;i++)

  {

   if(flag[i]==1)

   {

    for(j=1;j<=n;j++)

    {

     if(flag[j]==0)

     {

      if(dis[i][j]<min)

      {

       min=dis[i][j];

       newx=i;

       newy=j;

      }

     }

    }

   }

  }

  flag[newy]=1;

  sum+=dis[newx][newy]; 

 }

 return sum;

}

int visitedcount()     //已包含顶点个数

{

 count=0;

 for(i=1;i<=n;i++)

  if(flag[i]==1)

   count++;

 return count;

}

74、 题目描述:

   

    The Head Elder of the tropical island of Lagrishan has a problem、 A burst of foreign aid money was spent on extra roads between villages some years ago、 But the jungle overtakes roads relentlessly, so the large road network is too expensive to maintain、 The Council of Elders must choose to stop maintaining some roads、 The map above on the left shows all the roads in use now and the cost in aacms per month to maintain them、 Of course there needs to be some way to get between all the villages on maintained roads, even if the route is not as short as before、 The Chief Elder would like to tell the Council of Elders what would be the smallest amount they could spend in aacms per month to maintain roads that would connect all the villages、 The villages are labeled A through I in the maps above、 The map on the right shows the roads that could be maintained most cheaply, for 216 aacms per month、 Your task is to write a program that will solve such problems

输入:

    The input consists of one to 100 data sets, followed by a final line containing only 0、 Each data set starts with a line containing only a number n, which is the number of villages, 1 < n < 27, and the villages are labeled with the first n letters of the alphabet, capitalized、 Each data set is completed with n-1 lines that start with village labels in alphabetical order、 There is no line for the last village、 Each line for a village starts with the village label followed by a number, k, of roads from this village to villages with labels later in the alphabet、 If k is greater than 0, the line continues with data for each of the k roads、 The data for each road is the village label for the other end of the road followed by the monthly maintenance cost in aacms for the road、 Maintenance costs will be positive integers less than 100、 All data fields in the row are separated by single blanks、 The road network will always allow travel between all the villages、 The network will never have more than 75 roads、 No village will have more than 15 roads going to other villages (before or after in the alphabet)、 In the sample input below, the first data set goes with the map above

输出:

    The output is one integer per line for each data set: the minimum cost in aacms per month to maintain a road system that connect all the villages、 Caution: A brute force solution that examines every possible set of roads will not finish within the one minute time limit

样例输入:

9

A 2 B 12 I 25

B 3 C 10 H 40 I 8

C 2 D 18 G 55

D 1 E 44

E 2 F 60 G 38

F 0

G 1 H 35

H 1 I 35

3

A 2 B 10 C 40

B 1 C 20

0

样例输出:

216

30

#include <iostream>

#include <vector>

#include <cstdio>

#include <algorithm>

#include <map>

using namespace std;

struct edge{

    char x;

    char y;

    int cost;

    edge(char a,char b,int c){

 x = a; y = b; cost = c;

    }

};

map<char,char> fa;

vector<char> V;

vector<edge> E;

edge *p;

char find(char x){

    if(x!=fa[x]) x = find(fa[x]);

    return fa[x];

}

bool comp(edge a,edge b){

    return acost<bcost;

}

int main(int argc,char* argv[]){

    //freopen("inputtxt","r",stdin);

    int N;

    while(cin>>N&&N){

 Vclear();

 Eclear();

 char a,b;

 int n,c;

 N--;

 while(N--){

     cin>>a>>n;

     Vpush_back(a);

     while(n--){

  cin>>b>>c;

  p = new edge(a,b,c);

  Epush_back(*p);

     }

 }

 for(int i=0;i<Vsize();i++){

     fa[V[i]] = V[i];

 }

 int cost = 0;

 sort(Ebegin(),Eend(),comp);

 for(int i=0;i<Esize();i++){

     //cout<<E[i]x<<" "<<E[i]y<<" "<<E[i]cost<<endl;

     char fx,fy;

     fx = find(E[i]x);

     fy = find(E[i]y);

     if(fx<fy){

  fa[fy] = fx;

  cost += E[i]cost;

     }

     else if(fx>fy){

  fa[fx] = fy;

  cost += E[i]cost;

     }

 }

 cout<<cost<<endl;

    }

    return 0;

}

75、 题目描述:

    省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不1定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。

输入:

    测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M (N, M < =100 );随后的 行对应村庄间道路的成本,每行给出1对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1M编号。当N0时,全部输入结束,相应的结果不要输出。

输出:

    对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。

样例输入:

3 3

1 2 1

1 3 2

2 3 4

1 3

2 3 2

0 100

样例输出:

3

?

#include<iostream>

#include<algorithm>

#include<memoryh>

 

using namespace std;

 

int N,M,father[110];

 

struct E{  

  int a,b,v;

}e[110];

 

bool cmp(const E& A,const E& B){ return Av<Bv;}

 

int find(int x){ return father[x]==-1 ? x : find(father[x]); }

 

bool Union(int x,int y){

  

  x=find(x); y=find(y);

  

  if(x==y) return false;

  else return father[y]=x;

}

 

void Kruskal(){

 

  int sum=0;

  for(int i=0;i<N;++i)

    if(Union(e[i]a,e[i]b) && M--) 

  sum+=e[i]v;

    

  if(M<=1) cout<<sum<<endl;

  else cout<<"?"<<endl;

}

 

int  main(){

 

  while(cin>>N>>M && N!=0){

     memset(father,-1,sizeof(father));

     for(int i=0;i<N;++i) 

    cin>>e[i]a>>e[i]b>>e[i]v;

     sort(e,e+N,cmp);

     Kruskal();

  }

}

76题目描述:

    省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不1定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。

输入:

    测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。

    当N0时输入结束。

输出:

    每个测试用例的输出占1行,输出全省畅通需要的最低成本。

样例输入:

3

1 2 1 0

1 3 2 0

2 3 4 0

3

1 2 1 0

1 3 2 0

2 3 4 1

3

1 2 1 0

1 3 2 1

2 3 4 1

0

样例输出:

3

1

0

#include <stdioh>

#include <algorithm>

using namespace std;

#define MAX 5000

int father[101];

int w[MAX], u[MAX], v[MAX], r[MAX];

bool cmp(const int i, const int j) {return w[i]<w[j];}

int find(int x)

{

    int fx, tx = x;

    while(tx != father[tx]) { tx = father[tx];}

    fx = tx;

    while(x != father[x])

    {

 tx = x;

 x = father[x];

 father[tx] = fx;

    }

    return x;

}

int main()

{

    //freopen("JDOJ1028IN", "r", stdin);

    int n, flag;

    while(scanf("%d", &n), n)

    {

 int t = (n*(n-1))/2;

 for(int i=0; i<=n; i++) father[i] = i;

 for(int i=0; i<=t; i++) r[i] = i;

 for(int i=0; i<t; i++)

 {

     scanf("%d%d%d%d", &u[i], &v[i], &w[i], &flag);

     if(flag)

     {

  int fa = find(u[i]);

  int fb = find(v[i]);

  if(fa != fb)

  {

      if(i&1) father[fa] = fb;

      else father[fb] = fa;

  }

     }

 }

 sort(r, r+t, cmp);

 int sum = 0;

 for(int i=0; i<t; i++)

 {

     int e = r[i];

     int fu = find(u[e]);

     int fv = find(v[e]);

     if(fu != fv)

     {

  sum += w[e];

  if(i&1) father[fu] = fv;

  else father[fv] = fu;

     }

 }

 printf("%d\n", sum);

    }//while(1);

    return 0;

}

77、 题目描述:

在每年的校赛里,所有进入决赛的同学都会获得1件很漂亮的t-shirt。但是每当我们的工作人员将上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

输入:

输入包括多组数据。每组数据第1行是两个整数NMN<=100M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数ABC1<=A,B<=N,1<=C<=1000,表示在路口A与路口B之间有1条路,我们的工作人员需要C分钟的时间走过这条路。输入保证至少存在1条商店到赛场的路线。

当输入为两个0时,输入结束。

输出:

对于每组输入,输出1行,表示工作人员从商店走到赛场的最短时间。

样例输入:

2 1

1 2 3

3 3

1 2 5

2 3 5

3 1 2

0 0

样例输出:

3

2

#include <cstdio>

const short INF=10000;

int main()

{

    //freopen("Maintxt", "r", stdin);

    short n,m,a,b,c;

    while(scanf("%hd %hd",&n,&m)==2)

    {

 if(n==0&&m==0) break;

 short *g=new short[(n+1)*(n+1)];

 for(int i=0;i<n+1;++i)

     for(int j=0;j<n+1;++j)

     {

  if(i==j) *(g+i*(n+1)+j)=0;

  else *(g+i*(n+1)+j)=INF;

     }

 for(int i=0;i<m;++i)

 {

     scanf("%hd %hd %hd",&a,&b,&c);

     *(g+a*(n+1)+b)=c;

     *(g+b*(n+1)+a)=c;

 }

 short *set=new short[n+1];

 short *dist=new short[n+1];

 for(int i=0;i<n+1;++i) *(set+i)=0;

 dist[1]=0;

 set[1]=1;

 for(int j=2;j<n+1;++j) dist[j]=*(g+n+1+j);

 short minP;

 do

 {

     minP=-1;

     for(int i=1;i<n+1;i++)

     {

  if(set[i]==1) continue;

  if(minP==-1||dist[i]<dist[minP]) minP=i;

     }

     if(minP!=-1)

     {

  for(int i=1;i<n+1;++i)

  {

      if(set[i]==1) continue;

      if(*(g+minP*(n+1)+i)+dist[minP]<dist[i]) dist[i]=*(g+minP*(n+1)+i)+dist[minP];

  }

  //minP must greater than 0 or the heap memory will be corrupted

  set[minP] = 1;

     }

 }

 while(minP!=-1);

 printf("%hd\n",dist[n]);

 delete[] g;

 delete[] set;

 delete[] dist;

    }

    //fclose(stdin);

    return 0;

}

78、 题目描述:

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

输入:

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示ab之间有1条边,且其长度为d,花费为p。最后1行是两个数 s,t;起点s,终点tnm0时输入结束。

(1<n<=1000, 0<m<100000, s != t)

输出:

输出 1行有两个数, 最短距离及其花费。

样例输入:

3 2

1 2 5 6

2 3 4 5

1 3

0 0

样例输出:

9 11

#include<iostream>

using namespace std;

const long MAX=1000;

const long BIAN=100000;

long map[MAX][MAX];

long Huafei[MAX][MAX];

long visit[MAX];

long path[MAX];

long Point;

int flag;

void Mappath(long G[][MAX],long GG[][MAX],long u,long v,long i,long &Minleng,long &Mincost)

{

  long j;

     if(path[i]==v)

     {

     long temp=0;

        for(j=0;j<=(i-1);j++)

      temp=temp+G[path[j]][path[j+1]];

     if(flag==0){flag++;Minleng=temp;}

     else

     {if(temp<Minleng)

     { 

      Minleng=temp;

      

     }}

     }

     else

     {

     j=0;

        while(j<Point)

     {

     if(G[path[i]][j]!=(-1)&&visit[j]==0)

     {

     visit[j]=1;

     path[i+1]=j;

     Mappath(G,GG,u,v,i+1,Minleng,Mincost);

     visit[j]=0;

     }

     j++;

     }

     

     }

void XMappath(long G[][MAX],long GG[][MAX],long u,long v,long i,long &Minleng,long &Mincost)

{

  long j;

     if(path[i]==v)

     {

     long temp=0;

       for(j=0;j<=(i-1);j++)

    temp=temp+G[path[j]][path[j+1]];

     if(temp==Minleng)

     { 

      temp=0;

     for(j=0;j<=(i-1);j++)

     temp=temp+GG[path[j]][path[j+1]];

     if(flag==0){flag++;Mincost=temp;}

     else {if(temp<Mincost)Mincost=temp;}

      

     }

     }

     else

     {

     j=0;

        while(j<Point)

     {

     if(G[path[i]][j]!=(-1)&&visit[j]==0)

     {

     visit[j]=1;

     path[i+1]=j;

     XMappath(G,GG,u,v,i+1,Minleng,Mincost);

     visit[j]=0;

     }

     j++;

     }

     

     }

int main()

{

   long n,m;

  //  FILE *stream;

  //  stream=freopen("1txt","r",stdin);

    while(cin>>n>>m)

    {

    if(n==0&&m==0)break;

    long i,j;

    long juli,huafei;

    long k;

    for(i=0;i<n;i++)

     for(j=0;j<n;j++)

     {

      map[i][j]=(-1);

     map[j][i]=(-1);

     Huafei[i][j]=(-1);

     Huafei[j][i]=(-1);

     

     }

    for(k=0;k<m;k++)

    {

    cin>>i>>j>>juli>>huafei;

    map[i-1][j-1]=juli;

    map[j-1][i-1]=juli;

    Huafei[i-1][j-1]=huafei;

    Huafei[j-1][i-1]=huafei;

    }

    long qidian,zongdian;

    cin>>qidian>>zongdian;

    qidian--;

    zongdian--;

   long zuiduanlujin;

   long zuishaohuafei;

    for(i=0;i<MAX;i++)visit[i]=0;

    path[0]=qidian;

    visit[qidian]=1;

    Point=n;

    flag=0;

   Mappath(map,Huafei,qidian,zongdian,0,zuiduanlujin,zuishaohuafei);

       for(i=0;i<MAX;i++)visit[i]=0;

    path[0]=qidian;

    visit[qidian]=1;

    Point=n;

   flag=0;

     XMappath(map,Huafei,qidian,zongdian,0,zuiduanlujin,zuishaohuafei);

   cout<<zuiduanlujin<<" "<<zuishaohuafei<<endl;

    

    }

return 0;

}

79、 题目描述:

N个城市,标号从0N-1M条道路,第K条道路(K0开始)的长度为2^K,求编号为0的城市到其他城市的最短距离

输入:

1行两个正整数N2<=N<=100M(M<=500),表示有N个城市,M条道路

接下来M行两个整数,表示相连的两个城市的编号

输出:

N-1行,表示0号城市到其他城市的最短路,如果无法到达,输出-1,数值太大的以MOD 100000 的结果输出。

样例输入:

4 4

1 2

2 3

1 3

0 1

样例输出:

8

9

11

#include<iostream>

#include<vector>

#include<cstdio>

#include<algorithm>

#include<stringh>

using namespace std;

int data[200][200];

vector<int>dis[200];

int s[200];

int n,m;

long long Pow(int n)

{

 if(n==1)

  return 2;

 else if(n==0)

  return 1;

 if((n&1)==1)

  return 2*Pow(n-1)%100000;

 else

 {

  long long t=Pow(n>>1)%100000;

  return t*t%100000;

 }

}

vector<int> operator +(vector<int>vec,int data)

{

 vector<int>temp;

 sort(vecbegin(),vecend());

 vector<int>::iterator it=vecbegin();

 for(;it!=vecend();it++)

 {

  if(*it==data)

  {

   *it++;

   temp=vec;

   return temp;

  }

 }

 temp=vec;

 temppush_back(data);

 return temp;

}

bool operator < (vector<int> vec, vector<int>vec2)

{

 sort(vecbegin(),vecend());

 sort(vec2begin(),vec2end());

 vector<int>::iterator it=vecend(),it2=vec2end();

 it--;

 it2--;

 while(it!=vecbegin()&& it2!=vec2begin())

 {

  if(*it<*it2)

   return true;

  else if(*it>*it2)

   return false;

  else 

  {

   it--;

   it2--;

  }

 }

 if(*it==*it2)

  return vecsize()<vec2size();

 else

  return *it<*it2; 

}

int main()

{

 while(scanf("%d %d",&n,&m)!=EOF)

 {

  memset(data,-1,sizeof(data));

  int s1,s2;

  int k=0;

  for(int i=0;i<m;i++)

  {

   scanf("%d %d",&s1,&s2);

   data[s1][s2]=k;

   data[s2][s1]=k++;

  }

///////////////////////////////////

  memset(s,0,sizeof(s));

  for(int i=0;i<n;i++)

  {

   dis[i]clear();

   dis[i]push_back(1000);

  }

  for(int i=0;i<n;i++)

   if(data[0][i]!=-1)

   {

    dis[i]clear();

    dis[i]push_back(data[0][i]);

   }

  s[0]=1;

  int u=0;

  for(int i=1;i<n;i++)

  {

   vector<int>mindis;

   mindispush_back(1000);

   for(int j=0;j<n;j++)

   {

    if(s[j]==0 && dis[j]<mindis)

    {

     u=j;

     mindis=dis[j];

    }

   }

   s[u]=1;

   for(int j=0;j<n;j++)

   {

    if(s[j]==0 && data[u][j]!=-1 && 

    dis[u]+data[u][j]<dis[j])

    {

     dis[j]=dis[u]+data[u][j];

    }

   }

  }

 ////////////////////////////////

  for(int i=1;i<n;i++)

  {

   long long length=0;

   if(dis[i]size()==1&&dis[i][0]==1000)

   {

    cout<<"-1"<<endl;

    continue;

   }

   for(int j=0;j<dis[i]size();j++)

   {

    /*我擦,在这里纠结了好久,没有取余,白WAN*/

    length+=Pow(dis[i][j]);

    length%=100000;

   }

   cout<<length<<endl;

  }

 }

 return 0;

}

80、 题目描述:

    The country is facing a terrible civil war----cities in the country are divided into two parts supporting different leaders、 As a merchant, Mr、 M does not pay attention to politics but he actually knows the severe situation, and your task is to help him reach home as soon as possible、 

    "For the sake of safety,", said MrM, "your route should contain at most 1 road which connects two cities of different camp"

    Would you please tell Mr、 M at least how long will it take to reach his sweet home?

输入:

    The input contains multiple test cases

    The first line of each case is an integer N (2<=N<=600), representing the number of cities in the country

    The second line contains one integer M (0<=M<=10000), which is the number of roads

    The following M lines are the information of the roads、 Each line contains three integers A, B and T, which means the road between city A and city B will cost time T、 T is in the range of [1,500]

    Next part contains N integers, which are either 1 or 2、 The i-th integer shows the supporting leader of city i、 

    To simplify the problem, we assume that Mr、 M starts from city 1 and his target is city 2、 City 1 always supports leader 1 while city 2 is at the same side of leader 2、 

    Note that all roads are bidirectional and there is at most 1 road between two cities

Input is ended with a case of N=0

输出:

    For each test case, output one integer representing the minimum time to reach home

    If it is impossible to reach home according to Mr、 M's demands, output -1 instead

样例输入:

2

1

1 2 100

1 2

3

3

1 2 100

1 3 40

2 3 50

1 2 1

5

5

3 1 200

5 3 150

2 5 160

4 3 170

4 2 170

1 2 2 2 1

0

样例输出:

100

90

540

#include <stdioh>

#include <vector>

using namespace std;

struct E{

 int next;

 int t;

};

vector <E> edge[610];

bool mark[610];

int time[610];

int owner[610];

int main(){

 int n,m;

 while(scanf("%d",&n)!=EOF && n!=0){

  scanf("%d",&m);

  for(int i=1;i<=n;i++){

   edge[i]clear();

  }

  int a,b,t;

  for(int i=0;i<m;i++){

   scanf("%d%d%d",&a,&b,&t);

   E tmp;

   tmpnext=b;

   tmpt=t;

   edge[a]push_back(tmp);

   tmpnext=a;

   edge[b]push_back(tmp);

  }

  for(int i=1;i<=n;i++){

   mark[i]=false;

   time[i]=-1;

   scanf("%d",&owner[i]); 

  }

  for(int i=1;i<=n;i++){

   if(owner[i]==2){

    for(int j=0;j<edge[i]size();j++){

     if(owner[edge[i][j]next]==1){

      edge[i][j]t=0;

     }

    }

   }

  }

  time[1]=0;

  mark[1]=true;

  int newp=1;

  for(int i=1;i<n;i++){

   for(int j=0;j<edge[newp]size();j++){

    int next_=edge[newp][j]next;

    int time_=edge[newp][j]t;

    if(mark[next_]==true)

     continue;

    if(time_==0)

     continue;

    if(time[next_]==-1 || time[next_]>time[newp]+time_){

     time[next_]=time[newp]+time_;

    }

   }

    int min=1000;

    for(int j=1;j<=n;j++){

     if(mark[j]==true)

      continue;

     if(time[j]==-1)

      continue;

     if(time[j]<min){

      min=time[j];

      newp=j;

     }

    }

    mark[newp]=true;

   }

   if(time[2]!=-1)

    printf("%d\n",time[2]);

   else

    printf("-1\n");

 }

 return 0;

}

81、 题目描述:

ACM-DIY is a large QQ group where many excellent acmers get together、 It is so harmonious that just like a big family、 Every day,many "holy cows" like HH, hh, AC, ZT, lcc, BF, Qinz and so on chat on-line to exchange their ideas、 When someone has questions, many warm-hearted cows like Lost will come to help、 Then the one being helped will call Lost "master", and Lost will have a nice "prentice"、 By and by, there are many pairs of "master and prentice"、 But then problem occurs: there are too many masters and too many prentices, how can we know whether it is legal or not?We all know a master can have many prentices and a prentice may have a lot of masters too, it's legal、 Neverthelesssome cows are not so honest, they hold illegal relationship、 Take HH and 3xian for instant, HH is 3xian's master and, at the same time, 3xian is HH's master,which is quite illegal! To avoid this,please help us to judge whether their relationship is legal or not、 Please note that the "master and prentice" relation is transitive、 It means that if A is B's master ans B is C's master, then A is C's master

输入:

The input consists of several test cases、 For each case, the first line contains two integers, N (members to be tested) and M (relationships to be tested)(2 <= N, M <= 100)、 Then M lines follow, each contains a pair of (x, y) which means x is y's master and y is x's prentice、 The input is terminated by N = 0TO MAKE IT SIMPLE, we give every one a number (0, 1, 2,、、、, N-1)、 We use their numbers instead of their names

输出:

For each test case, print in one line the judgement of the messy relationshipIf it is legal, output "YES", otherwise "NO"

样例输入:

3 2

0 1

1 2

2 2

0 1

1 0

0 0

样例输出:

YES

NO

#include <cstdio>

#include <queue>

using namespace std;

struct relation

{

    short a;

    short b;

};

short findStart(relation *r,short n,short m,short mark[])

{

    bool find = false;

    for(short i=0;i<n;++i)

    {

 if(mark[i]==0) continue;

 find = false;

 for(short j=0;j<m;++j)

 {

     if((r+j) >a==0&&(r+j) >b==0) continue;

     if((r+j) >b==i)

     {

  find = true;

  break;

     }

 }

 if(!find) return i;

    }

    return -1;

}

short deleteX(relation *r,short x,short m,short mark[])

{

    if(x>-1)

    {

 mark[x]=0;

 for(int i=0;i<m;++i)

 {

     if((r+i) >a==x)

     {

  (r+i) >a=0;

  (r+i) >b=0;

     }

 }

    }

    return x;

}

int main()

{

    //freopen("Maintxt", "r", stdin);

    short n,m;

    while(scanf("%hd %hd",&n,&m)==2)

    {

 if(n==0) break;

 relation *r = new relation[m];

 for(int i=0;i<m;++i) scanf("%hd %hd",&((r+i) >a),&((r+i) >b));

 short *mark=new short[n];

 for(int i=0;i<n;++i) mark[i]=1;

 while(deleteX(r,findStart(r,n,m,mark),m,mark)>-1);

 bool yes = true;

 for(int i=0;i<n;++i)

     if(mark[i]==1)

     {

  yes = false;

  break;

     }

 if(yes) printf("YES\n");

 else printf("NO\n");

 delete[] r;

 delete[] mark;

    }

    //fclose(stdin);

    return 0;

}

82、 题目描述:

N个比赛队(1<=N<=500),编号依次为123,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1P2,用P1P2表示,排名时P1P2之前。现在请你编程序确定排名。

输入:

输入有若干组,每组中的第1行为二个数N1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1P2表示即P1队赢了P2队。

输出:

给出1个符合要求的排名。输出时队伍号之间有空格,最后1名后面没有空格。

其他说明:符合条件的排名可能不是唯1的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保1定能有1个符合要求的排名。

样例输入:

4 3

1 2

2 3

4 3

样例输出:

1 2 4 3

#include <cstdio>

struct r

{

    short p1,p2;

};

short find(short *mark,r *rs,short n,short m)

{

    bool f=false;

    for(int i=1;i<=n;++i)

    {

 if(!mark[i]) continue;

 f=false;

 for(int j=0;j<m;++j)

 {

     if((rs+j) >p2==i)

     {

  f=true;

  break;

     }

 }

 if(!f) return i;

    }

    return -1;

}

short deleteX(short x,short *mark,r *rs,short n,short m)

{

    if(x>-1)

    {

 mark[x]=0;

 for(int i=0;i<m;++i)

 {

     if((rs+i) >p1==x)

     {

  (rs+i) >p1=-1;

  (rs+i) >p2=-1;

     }

 }

    }

    return x;

}

int main()

{

    short n,m;

    while(scanf("%hd %hd",&n,&m)==2)

    {

 r *rs = new r[m];

 short *mark=new short[n+1],*result = new short[n+1],resultLen=0;

 for(int i=0;i<n+1;++i) mark[i]=1;

 for(int i=0;i<m;++i) scanf("%hd %hd",&(rs+i) >p1,&(rs+i) >p2);

 while((result[resultLen++]=deleteX(find(mark,rs,n,m),mark,rs,n,m))>-1);

 printf("%hd",result[0]);

 for(int i=1;i<resultLen-1;++i) printf(" %hd",result[i]);

 putchar('\n');

 delete[] rs;

 delete[] mark;

 delete[] result;

    }

    return 0;

}

83、 题目描述:

1群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打1场比赛。

球赛的要求如下:

如果A打败了BB又打败了C,而AC之间没有进行过比赛,那么就认定,A1定能打败C

如果A打败了BB又打败了C,而且,C又打败了A,那么ABC三者都不可能成为冠军。

根据这个要求,无需循环较量,或许就能确定冠军。你的任务就是面对1群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。

输入:

输入含有1些选手群,每群选手都以1个整数n(n<1000)开头,后跟n对选手的比赛结果,比赛结果以1对选手名字(中间隔1空格)表示,前者战胜后者。如果n0,则表示输入结束。

输出:

对于每个选手群,若你判断出产生了冠军,则在1行中输出“Yes”,否则在1行中输出“No”。

样例输入:

3

Alice Bob

Smith John

Alice Smith

5

a c

c d

d e

b e

a d

0

样例输出:

Yes

No

#include<stdioh>

#include<stringh>

#include<string>

#include<map>

using namespace std;

map<string,int> M;

int data[2002];

int main(){

    char str1[101],str2[101];

    int n;

    while(scanf("%d",&n)&&n!=0){

 Mclear();

 int size=0;

 for(int i=0;i<n*2;i++)data[i]=0;

 while(n--){

   scanf("%s%s",str1,str2);

   string a=str1,b=str2;

   int sib;

   if(Mfind(a)==Mend())M[a]=size++;

   if(Mfind(b)==Mend()){

   sib=size;

   M[b]=size++;

   } 

   else sib=M[b];

   data[sib]++;

 }

 int num=0;

 for(int i=0;i<size;i++)

  if(data[i]==0)num++;

 puts(num==1?"Yes":"No");

    }

    return 0;

}

84、 题目描述:

    用小于等于n元去买100只鸡,大鸡5/只,小鸡3/,还有1/3元每只的1种小鸡,分别记为x,y,z只。编程求解x,y,z所有可能解。

输入:

    测试数据有多组,输入n

输出:

    对于每组输入,请输出x,y,z所有可行解,按照xyz依次增大的顺序输出。

样例输入:

40

样例输出:

x=0,y=0,z=100

x=0,y=1,z=99

x=0,y=2,z=98

x=1,y=0,z=99

#include <iostream>

#include <cstdio>

using namespace std;

int N;

int main()

{

 while(cin>>N)

 {

  for(int i = 0; i<=100; i++)

   for(int j = 0; j<=100; j++)

   {

    int sum = 14*i+8*j;

    if(sum<=3*N-100)

    {

     printf("x=%d,y=%d,z=%d\n",i,j,100-i-j);

    }

   }

 }

 return 0;

}

85、 题目描述:

abc均是09之间的数字,abcbcc是两个三位数,且有:abc+bcc=532。求满足条件的所有abc的值。

输入:

题目没有任何输入。

输出:

请输出所有满足题目条件的abc的值。

abc之间用空格隔开。

每个输出占1行。

样例输入:

样例输出:

#include<iostream>

using namespace std;

int main()

{

 int a,b,c;

 for(a=1;a<5;a++)

  for(b=1;b<5;b++)

   for(c=0;c<=9;c++)

 if((a*100+b*10+c+b*100+c*10+c)==532)

  cout<<a<<" "<<b<<" "<<c<<endl;

 return 0;

}

86、 题目描述:

输入10个数,要求输出其中的最大值。

输入:

测试数据有多组,每组10个数。

输出:

对于每组输入,请输出其最大值(有回车)。

样例输入:

10 22 23 152 65 79 85 96 32 1

样例输出:

max=152

#include <iostream>

using namespace std;

int main()

{

 int max = -1;

 int i = 0;

 int tmp;

 while(cin>>tmp)

 {

  if(max <tmp)

  {

   max = tmp;

  }

  if(0 == ++i%10)

  {

   cout << "max=" << max << endl;

   max = -1;

  }

  

 }

 return 0;

}

87、 题目描述:

Ignatius被魔王抓走了,1天魔王出差去了,这可是Ignatius逃亡的好机会、魔王住在1个城堡里,城堡是1A*B*C的立方体,可以被表示成AB*C的矩阵,刚开始Ignatius被关在(0,0,0)的位置,离开城堡的门在(A-1,B-1,C-1)的位置,现在知道魔王将在T分钟后回到城堡,Ignatius每分钟能从1个坐标走到相邻的六个坐标中的其中1个、现在给你城堡的地图,请你计算出Ignatius能否在魔王回来前离开城堡(只要走到出口就算离开城堡,如果走到出口的时候魔王刚好回来也算逃亡成功),如果可以请输出需要多少分钟才能离开,如果不能则输出-1

输入:

输入数据的第1行是1个正整数K,表明测试数据的数量、每组测试数据的第1行是四个正整数A,B,CT(1<=A,B,C<=50,1<=T<=1000),它们分别代表城堡的大小和魔王回来的时间、然后是A块输入数据(先是第0,然后是第1,2块、、、、、、),每块输入数据有B,每行有C个正整数,代表迷宫的布局,其中0代表路,1代表墙。

输出:

对于每组测试数据,如果Ignatius能够在魔王回来前离开城堡,那么请输出他最少需要多少分钟,否则输出-1

样例输入:

1

3 3 4 20

0 1 1 1

0 0 1 1

0 1 1 1

1 1 1 1

1 0 0 1

0 1 1 1

0 0 0 0

0 1 1 0

0 1 1 0 

样例输出:

11

#include <stdioh>

#include <queue>

using std::queue;

const short MAX = 50;

short k, a, b, c, t;

short map[MAX][MAX][MAX];

struct State {

    short x, y, z, t;

};

struct Move {

    short dx, dy, dz;

};

Move movs[6]={

    {0, 0, 1},

    {0, 0, -1},

    {1, 0, 0},

    {0, 1, 0},

    {-1, 0, 0},

    {0, -1, 0}

};

short bfs(State s) {

    State newState, currentState;

    queue<State> q;

    qpush(s);

    map[sz][sx][sy] = 1;

    while (!qempty()) {

 currentState = qfront(); qpop();

 if (currentStatex == b-1 &&

     currentStatey == c-1 &&

     currentStatez == a-1) {

     return currentStatet;

 }

 for (short i=0; i < 6; ++i) {

     newStatex = currentStatex + movs[i]dx;

     newStatey = currentStatey + movs[i]dy;

     newStatez = currentStatez + movs[i]dz;

     newStatet = currentStatet + 1;

     if (newStatex < 0 || newStatex >= b ||

  newStatey < 0 || newStatey >= c ||

  newStatez < 0 || newStatez >= a) continue;

     if (map[newStatez][newStatex][newStatey] == 1) continue;

     qpush(newState);

     map[newStatez][newStatex][newStatey] = 1;

 }

    }

    return -1;

}

int main() {

    scanf("%hd", &k);

    for (short i=0; i < k; ++i) {

 scanf("%hd %hd %hd %hd", &a, &b, &c, &t);

 for (short i=0; i < a; ++i) {

     for (short j=0; j < b; ++j) {

  for (short k=0; k < c; ++k) {

      scanf("%hd", &map[i][j][k]);

  }

     }

 }

 State s = {0, 0, 0, 0};

 short result = 0;

 printf("%hd\n", (result = bfs(s)) <= t?result:-1);

    }

    return 0;

}

88、 题目描述:

大家1定觉的运动以后喝可乐是1件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou1起分享这1瓶可乐,而且1定要喝的和seeyou1样多。但seeyou的手中只有两个杯子,它们的容量分别是毫升和毫升 可乐的体积为S<101)毫升(正好装满1,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M101S0N0M0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"

输入:

三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。

输出:

如果能平分的话请输出最少要倒的次数,否则输出"NO"

样例输入:

7 4 3

4 1 3

0 0 0

样例输出:

NO

3

#include <cstdio>

#include <queue>

using std::queue;

const short MAX = 101;

short N, M ,S;

bool map[MAX][MAX];

struct State {

    short n, m, s, t;

};

void poura2b(short &a, short &b, short aMax, short bMax) {

    //need a temporary variable to hold the original value of b

    short bOld = b;

    b = b + a;

    if (b > bMax) b = bMax;

    a = a - (b - bOld);

    if (a < 0) a = 0;

}

short solve(short n, short m, short s) {

    queue<State> q;

    State cur = {n, m , s, 0}, news;

    qpush(cur);

    while (!qempty()) {

 cur = qfront(); qpop();

 if (curn + curm == curs) return curt;

 news = cur;

 poura2b(newsn, newsm, N, M); newst++;

 if (map[newsn][newsm] == false) {

     qpush(news);

     map[newsn][newsm] = true;

 }

 news = cur;

 poura2b(newsm, newsn, M, N); newst++;

 if (map[newsn][newsm] == false) {

     qpush(news);

     map[newsn][newsm] = true;

 }

 news = cur;

 poura2b(newsn, newss, N, S); newst++;

 if (map[newsn][newsm] == false) {

     qpush(news);

     map[newsn][newsm] = true;

 }

 news = cur;

 poura2b(newss, newsn, S, N); newst++;

 if (map[newsn][newsm] == false) {

     qpush(news);

     map[newsn][newsm] = true;

 }

 news = cur;

 poura2b(newsm, newss, M, S); newst++;

 if (map[newsn][newsm] == false) {

     qpush(news);

     map[newsn][newsm] = true;

 }

 news = cur;

 poura2b(newss, newsm, S, M); newst++;

 if (map[newsn][newsm] == false) {

     qpush(news);

     map[newsn][newsm] = true;

 }

    }

    return -1;

}

int main() {

    while (scanf("%hd %hd %hd", &S, &N, &M) == 3) {

 if (N == 0 && S == 0 && M == 0) break;

 if (S&1) {

     puts("NO");

     continue;

 }

 for (int i = 0; i < MAX; ++i)

     for (int j = 0; j < MAX; ++j)

  map[i][j] = false;

 map[0][0] = true;

 short r = solve(0, 0, S);

 if (r == -1) printf("NO\n");

 else

     printf("%hd\n", r);

    }

    return 0;

}

89、 题目描述:

19世纪末,在欧州的商店中出售1种智力玩具,在1块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是1次只能移动1个盘,且不允许大盘放在小盘的上面。现在我们改变游戏的玩法,不允许直接从最左()边移到最右()(每次移动1定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面。Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在请你帮助她。现在有N个圆盘,她至少多少次移动才能将这些圆盘从最左边移到最右边?

输入:

包含多组数据,每次输入1N(1<=N=35)

输出:

对于每组数据,输出移动最小的次数。

样例输入:

1

3

12

样例输出:

2

26

531440

#include<stdioh>

long long F(int n)

{

    if(n==1) return 2;

    else

 return 3*F(n-1)+2;

}

int main()

{

    int n;

    while(scanf("%d",&n)!=EOF)

    {

 printf("%lld\n",F(n));

    }

    return 0;

}

90、 题目描述:

 

A ring is compose of n circles as shown in diagram、 Put natural number 1, 2, 、、、, n into each circle separately, and the sum of numbers in two adjacent circles should be a prime

Note: the number of first circle should always be 1

输入:

n (1 < n < 17)

输出:

The output format is shown as sample below、 Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely、 The order of numbers must satisfy the above requirements、 Print solutions in lexicographical order

You are to write a program that completes above process

Print a blank line after each case

样例输入:

6

8

样例输出:

Case 1:

1 4 3 2 5 6

1 6 5 2 3 4

Case 2:

1 2 3 8 5 6 7 4

1 2 5 8 3 4 7 6

1 4 7 6 5 8 3 2

1 6 7 4 3 8 5 2

#include<iostream>

#include<cstdio>

#include<limitsh>

#include<memoryh>

#include<queue>

#include<string>

#include<vector>

using namespace std;

bool prime[100],mark[20];

int n,ans[50];

void p()

{

    int i,j,k;

    memset(prime,0,100*sizeof(bool));

    for(i=2;i<100;i++)

    {

 if(!prime[i])

 {

     for(j=i;i*j<100;j++)

  prime[i*j]=true;

 }

    }

}

void init()

{

    memset(mark,0,sizeof(mark));

}

void print()

{

    printf("1");

    for(int i=2;i<=n;i++)

 printf(" %d",ans[i]);

    printf("\n");

}

void print(int j)

{

    printf("1");

    for(int i=2;i<=j;i++)

 printf(" %d",ans[i]);

    printf("\n");

}

void dfs(int i)

{

    //cout<<i<<"   begin"<<endl;

    if(i==n&&!prime[ans[1]+ans[n]])

    {

 print();

 return ;

    }

    for(int j=2;j<=n;j++)

    {

 if(i==5)

 {

     for(int k=2;k<=6;k++)

     {

  if(!mark[k])

  {

  //  cout<<k<<" unvsed "<<endl;

  //  cout<<ans[i]<<" "<<ans[i]+k<<endl;

      ;

  }

     }

  

 }

 if(!mark[j]&&!prime[ans[i]+j])

 {

     //cout<<ans[i]<<" "<<j<<"  ";

     mark[j]=true;

     ans[i+1]=j;

     dfs(i+1);

     mark[j]=false;

 }

    }

//  print(i+1);

//  cout<<i<<"   end"<<endl;

}

int main()

{

    int i,j,k,cnt=1;

    char temp[101];

    //freopen("F:\\testtxt","r",stdin);

    p();

    ans[1]=1;

    while(scanf("%d",&n)!=EOF)

    {

 init();

 printf("Case %d:\n",cnt++);

 dfs(1);

 printf("\n");

    }

    return 0;

}

91、 题目描述:

The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits、 GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots、 It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil、 A plot containing oil is called a pocket、 If two pockets are adjacent, then they are part of the same oil deposit、 Oil deposits can be quite large and may contain numerous pockets、 Your job is to determine how many different oil deposits are contained in a grid

输入:

The input file contains one or more grids、 Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space、 If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100、 Following this are m lines of n characters each (not counting the end-of-line characters)、 Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket

输出:

For each grid, output the number of distinct oil deposits、 Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally、 An oil deposit will not contain more than 100 pockets

样例输入:

1 1

*

3 5

*@*@*

**@**

*@*@*

1 8

@@****@*

5 5

****@

*@@*@

*@**@

@@@*@

@@**@

0 0

样例输出:

0

1

2

2

#include<stdioh>

 

#define N 101

 

char oil[N][N];

//bool mark[N][N];

 

int go[][2]={0,1,0,-1,1,0,-1,0,

1,1,1,-1,-1,1,-1,-1};

int m,n;

void make(int x,int y){

    //if(oil[x][y]!='@' || mark[x][y]==true)return;

    oil[x][y]='*';

    for(int i=0;i<8;i++){

 int a=x+go[i][0];

 int b=y+go[i][1];

 if(a<0||a>=m||b<0||b>=n)continue;

 if(oil[a][b]=='@'){

     //oil[a][b]='*';

     make(a,b);

 }

    }

}

 

int main(){

    int sum,i,j;

    while(1){

 sum=0;

 scanf("%d%d",&m,&n);

 if(m==0 && n==0)break;

 for(int i=0;i<m;i++){

     scanf("%s",oil[i]);

 }

 for(i=0;i<m;i++){

     for(j=0;j<n;j++){

  if(oil[i][j]=='@'){

      sum++;

      make(i,j);

  }

     }

 }

 printf("%d\n",sum);

    }

}

92、 题目描述:

给定1个由不同的小写字母组成的string,输出这个string的所有全排列。

我们假设对于小写字母有'a' < 'b' < 、、、 < 'y' < 'z',而且给定的string中的字母已经按照从小到大的顺序排列。

输入:

输入只有1行,是1个由不同的小写字母组成的string,已知string的长度在16之间。

输出:

输出这个string的所有排列方式,每行1个排列。要求字母序比较小的排列在前面。字母序如下定义:

已知S = s1s2、、、sk , T = t1t2、、、tk,则S < T 等价于,存在p (1 <= p <= k),使得

s1 = t1, s2 = t2, 、、、, sp - 1 = tp - 1, sp < tp成立。

样例输入:

abc

样例输出:

abc

acb

bac

bca

cab

cba

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

int main()

{

char str[7];

while(scanf("%s", str) != EOF)

{

  int len = strlen(str);

  do

  {

   printf("%s\n", str);

  }

  while(next_permutation(str, str + len));

  printf("\n");

}

return 0;

}

93、 题目描述:

The doggie found a bone in an ancient maze, which fascinated him a lot、 However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking、 He realized that the bone was a trap, and he tried desperately to get out of this maze

The maze was a rectangle with sizes N by M、 There was a door in the maze、 At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second)、 Therefore the doggie had to arrive at the door on exactly the T-th second、 In every second, he could move one block to one of the upper, lower, left and right neighboring blocks、 Once he entered a block, the ground of this block would start to sink and disappear in the next second、 He could not stay at one block for more than one second, nor could he move into a visited block、 Can the poor doggie survive? Please help him

输入:

The input consists of multiple test cases、 The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively、 The next N lines give the maze layout, with each line containing M characters、 A character is one of the following:

'X': a block of wall, which the doggie cannot enter; 

'S': the start point of the doggie; 

'D': the Door; or

'': an empty block

The input is terminated with three 0's、 This test case is not to be processed、 

输出:

For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise

样例输入:

4 4 5

SX

、、X

、、XD

、、、、

3 4 5

SX

、、X

、、、D

0 0 0

样例输出:

NO

YES

#include<stdioh>

 

int N,M,T,s;

 

int go[][2]={0,1,0,-1,-1,0,1,0};

char maze[7][7];

 

bool DFS(int x,int y,int t){

    s++;

    maze[x][y]='X';

    for(int i=0;i<4;i++){

 int a=x+go[i][0];

 int b=y+go[i][1];

 if(a<0||b<0||a>=N||b>=M)continue;

 if(maze[a][b]=='D'){

     if(t+1==T)return true;////

     else continue;

 }

 if(maze[a][b]==''){

     if(DFS(a,b,t+1))return true;

 }

    }

    maze[x][y]='';

    s--;

    return false;

}

int main(){

    int i,j,sx,sy;

    while(1){

 scanf("%d%d%d",&N,&M,&T);

 if(N==0 &&M==0&&T==0)break;

 for(i=0;i<N;i++){

     scanf("%s",maze[i]);

 }

 for(i=0;i<N;i++){

     for(j=0;j<M;j++){

  if(maze[i][j]=='S'){

      sx=i;

      sy=j;

  }

     }

 }

 s=0;

 //printf("%d,%d",sx,sy);

 if(DFS(sx,sy,0))puts("YES");

 else puts("NO");

    }

    return 0;

}

94、 题目描述:

N阶楼梯上楼问题:1次可以走两阶或1阶,问有多少种上楼方式。(要求采用非递归)

输入:

输入包括1个整数N,(1<=N<90)

输出:

可能有多组测试数据,对于每组数据,

输出当楼梯阶数是N时的上楼方式个数。

样例输入:

4

样例输出:

5

#include <iostream>

using namespace std;

//iArrayS中的元素复制都iArrayD

void int_array_copy(int iArrayD[],int iArrayS[])

{

 for(int i = 0; i <= iArrayS[0]; ++i)

 {

  iArrayD[i] = iArrayS[i];

 }

}

//将两个数组的元素相加

void int_array_add(int iArrayA[],int iArrayB[],int iArrayC[])

{

 int c = 0; //进位

 int tmp;

 int i;

 iArrayC[0] = iArrayB[0];

 for(i = 1; i <= iArrayA[0]; ++i)

 {

  tmp = iArrayA[i] + iArrayB[i] + c;

  iArrayC[i] = tmp % 10;

  c = tmp / 10;

 }

 while(i <= iArrayB[0])

 {

  tmp = iArrayB[i] + c;

  iArrayC[i] = tmp % 10;

  c = tmp / 10;

  i++;

 }

 if(c)

 {

  iArrayC[i] = c;

  iArrayC[0]++;

 }

}

void Nfloor(int n)

{

 int A[30],B[30],C[30];

    A[0] = 1;

 A[1] = 1;

 B[0] = 1;

    B[1] = 2;

  

 if(n == 1)

  cout << "1" << endl;

 else if(n == 2)

  cout << "2" << endl;

 else

 {

  n -= 2;

  while(n--)

  {

   int_array_add(A,B,C);

   int_array_copy(A,B);

   int_array_copy(B,C);

  }

  for(int i = C[0]; i >1; --i)

  {

   cout <<C[i];

  }

  cout << C[1] << endl;

 }

}

int main()

{

 int N;

 while(cin >> N)

 {

  Nfloor(N);

 }

 return 0;

}

95、 题目描述:

大家常常感慨,要做好1件事情真的不容易,确实,失败比成功容易多了!

做好“1件”事情尚且不易,若想永远成功而总从不失败,那更是难上加难了,就像花钱总是比挣钱容易的道理1样。

话虽这样说,我还是要告诉大家,要想失败到1定程度也是不容易的。比如,我高中的时候,就有1个神奇的女生,在英语考试的时候,竟然将40个单项选择题全部做错了!大家都学过概率论,应该知道出现这种情况的概率,所以至今我都觉得这是1件神奇的事情。如果套用1句经典的评语,我们可以这样总结:1个人做错1道选择题并不难,难的是全部做错,1个不对。

不幸的是,这种小概率事件又发生了,而且就在我们身边:

事情是这样的——HDU有个网名叫做8006的男性同学,结交网友无数,最近该同学玩起了浪漫,同时给n个网友每人写了1封信,这都没什么,要命的是,他竟然将所有的信都装错了信封!注意了,是全部装错哟!

现在的问题是:请大家帮可怜的8006同学计算1下,1共有多少种可能的错误方式呢?

输入:

输入数据包含多个多个测试实例,每个测试实例占用1行,每行包含1个正整数n1<n<=20),n表示8006的网友的人数。

输出:

对于每行输入请输出可能的错误方式的数量,每个实例的输出占用1行。

样例输入:

2

3

样例输出:

1

2

#include<stdioh>

 

long int F[21];

 

 

int main(){

F[1]=0;

F[2]=1;

int i;

 

for(i=3;i<21;i++)

    F[i]=(i-1)*(F[i-1]+F[i-2]); 

int n;

while(scanf("%d",&n)!=EOF)

   printf("%lld\n",F[n]); 

   

    return 0;

 

}

96、 题目描述:

名名的妈妈从外地出差回来,带了1盒好吃又精美的巧克力给名名(盒内共有 块巧克力,20 > N >0)。

妈妈告诉名名每天可以吃1块或者两块巧克力。

假设名名每天都吃巧克力,问名名共有多少种不同的吃完巧克力的方案。

示例:

如果N=1,则名名第1天就吃掉它,共有1种方案;

如果N=2,则名名可以第1天吃1块,第2天吃1块,也可以第1天吃2块,共有2种方案;

如果N=3,则名名第1天可以吃1块,剩2块,也可以第1天吃2块剩1块,所以名名共有2+1=3种方案;

如果N=4,则名名可以第1天吃1块,剩3块,也可以第1天吃2块,剩2块,共有3+2=5种方案。

现在给定N,请你写程序求出名名吃巧克力的方案数目。

输入:

输入只有1行,即整数N

输出:

可能有多组测试数据,对于每组数据,

输出只有1行,即名名吃巧克力的方案数。

样例输入:

4

样例输出:

5

#include<stdioh>

int js(int x,int y)

{int n,p=1,q=1,i;

n=x-y;

for(i=1;i<=y;i++)

p=p*i;

for(i=n-y+1;i<=n;i++)

q=q*i;

p=q/p;

return p;

}

int main()

{int i,k,z,n;

while(scanf("%d",&n)!=EOF)

{k=n/2;

z=1;

for(i=1;i<=k;i++)

z+=js(n,i);

printf("%d\n",z);

}

return 0;

}

97、 题目描述:

某国为了防御敌国的导弹袭击,开发出1种导弹拦截系统。但是这种导弹拦截系统有1个缺陷:虽然它的第1发炮弹能够到达任意的高度,但是以后每1发炮弹都不能高于前1发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。 

输入:

每组输入有两行,

1行,输入雷达捕捉到的敌国导弹的数量kk<=25),

2行,输入k个正整数,表示k枚导弹的高度,按来袭导弹的袭击时间顺序给出,以空格分隔。

输出:

每组输出只有1行,包含1个整数,表示最多能拦截多少枚导弹。

样例输入:

8

300 207 155 300 299 170 158 65

样例输出:

6

#include<stdioh>

#include<stringh>

#include<stdlibh>

#include<mathh>

int max;int n;

void  fun(int a[100],int i,int count)

{

 if(count>max){max=count ;}

 int j=0;

 for(j=i+1;j<n;j++)

 { 

   if(a[j]<=a[i])

    {

     fun(a,j,count+1);

    }

 } 

}

int main()

{

    

  int a[100];int i=0;

  while(scanf("%d",&n)!=EOF)

  {

   max=0;

  for(i=0;i<n;i++)

  {

   scanf("%d",&a[i]);

  } 

     for(i=0;i<n;i++)

  {

   fun(a,i,1);

  }

  printf("%d\n",max);

  }

  return 0;

}

98、 题目描述:

N位同学站成1排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形。

合唱队形是指这样的1种队形:设K位同学从左到右依次编号为1, 2, , K,他们的身高分别为T1, T2, , TK

则他们的身高满足T1 < T2 < … < Ti , Ti > Ti+1 > … > TK (1 <= i <= K)

你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入:

输入的第1行是1个整数N2 <= N <= 100),表示同学的总数。

1行有n个整数,用空格分隔,第i个整数Ti130 <= Ti <= 230)是第i位同学的身高(厘米)。

输出:

可能包括多组测试数据,对于每组数据,

输出包括1行,这1行只包含1个整数,就是最少需要几位同学出列。

样例输入:

8

186 186 150 200 160 130 197 220

样例输出:

4

#include <stdioh>

#include <stringh>

#define UNSOLVE -1

#define NMAX 102

#define MMX 240

int n;

int left[NMAX], right[NMAX];

int arr[NMAX];

void init_left() {

  for (int i = 0; i < n; ++ i) {

    int max = 1;

    for (int j = 0; j < i; ++ j) {

  if (arr[i] > arr[j])

 max = max > left[j] + 1 ? max : left[j] + 1;

    }

    left[i] = max;

  }

}

void init_right() {

  for (int i = n - 1; i >= 0; -- i) {

    int max = 1;

    for (int j = i + 1; j < n; ++ j) {

  if (arr[i] > arr[j])

 max = max > right[j] + 1 ? max : right[j] + 1;

    }

    right[i] = max;

  }

}

bool init() {

  if (scanf("%d", &n) == EOF) return false;

  for (int i = 0; i < n; ++ i) scanf("%d", &arr[i]);

  return true;

}

int solve() {

  init_left();

  init_right();

  int min = n;

  for (int i = 0; i < n; ++ i) {

    int temp = n - (left[i] + right[i] - 1);

    min = min < temp ? min : temp;

  }

  return min;

}

int main() {

  while (init()) {

    printf("%d\n", solve());

  }

  return 0;

}

99、 题目描述:

Find a longest common subsequence of two strings

输入:

First and second line of each input case contain two strings of lowercase character a…z、 There are no spaces before, inside or after the strings、 Lengths of strings do not exceed 100

输出:

For each case, output k – the length of a longest common subsequence in one line

样例输入:

abcd

cxbydz

样例输出:

2

#include<iostream>

#include<stringh>

using namespace std;

char str1[110],str2[110];

int Common(int a,int b)

{

 if(a==-1||b==-1)

  return 0;

 if(str1[a]==str2[b])

  return Common(a-1,b-1)+1;

 else 

  return Common(a-1,b)>Common(a,b-1)?Common(a-1,b):Common(a,b-1);

}

int main()

{

 int len;

 while(cin>>str1>>str2)

 {

  len=0;

  len=Common(strlen(str1) 1,strlen(str2) 1);

  cout<<len<<endl;

 }

 return 0;

}

100、 题目描述:

搬寝室是很累的,xhd深有体会、时间追述200679,那天xhd迫于无奈要从27号楼搬到3号楼,因为10号要封楼了、看着寝室里的n件物品,xhd开始发呆,因为n1个小于2000的整数,实在是太多了,于是xhd决定随便搬2*k件过去就行了、但还是会很累,因为2*k也不小是1个不大于n的整数、幸运的是xhd根据多年的搬东西的经验发现每搬1次的疲劳度是和左右手的物品的重量差的平方成正比(这里补充1,xhd每次搬两件东西,左手1件右手1)、示例xhd左手拿重量为3的物品,右手拿重量为6的物品,则他搬完这次的疲劳度为(6-3)^2 = 9、现在可怜的xhd希望知道搬完这2*k件物品后的最佳状态是怎样的(也就是最低的疲劳度),请告诉他吧。

输入:

每组输入数据有两行,1行有两个数n,k(2<=2*k<=n<2000)、第2行有n个整数分别表示n件物品的重量(重量是1个小于2^15的正整数)

输出:

对应每组输入数据,输出数据只有1个表示他的最少的疲劳度,每个1行、

样例输入:

2 1

1 3

样例输出:

4

#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

 

int main()

{

    const int MAX_SIZE=2000;

    int w[MAX_SIZE];

    int n,k;

    while(scanf("%d%d",&n,&k)>0)

    {

 int i,j;

  

 for(i=0;i<n;i++)

 {

     scanf("%d",&w[i]);

 }

 sort(w,w+n);

 for(i=0;i<n-1;i++)

 {

     w[i]=w[i+1]-w[i];

     w[i]*=w[i];

 }

  

 int minid,prev,next;

 int rslt=0;

 for(i=0;i<k;i++)

 {

     minid=-1;

     for(j=0;j<n-1;j++)

     {

  if(w[j]<0)   continue;

  if(minid<0 || w[j]<w[minid])  minid=j;

     }

     rslt+=w[minid];

     if(i==k-1)  break;

  

     for(prev=minid-1;prev>=0;prev--)

  if(w[prev]>=0)   break;

     for(next=minid+1;next<n-1;next++)

  if(w[next]>=0)   break;

     if(prev>=0 && next<n-1)   w[minid]=w[prev]+w[next]-w[minid];

     else    w[minid]=-1;

     if(prev>=0)  w[prev]=-1;

     if(next<n-1) w[next]=-1;

 }

  

 printf("%d\n",rslt);

    }

    return 0;

}

101、 题目描述:

 Tino wrote a long long story、 BUT! in Chinese、、、

So I have to tell you the problem directly and discard his long long story、 That is tino want to carry some oranges with "Carrying pole", and he must make two side of the Carrying pole are the same weight、 Each orange have its' weight、 So greedy tino want to know the maximum weight he can carry

输入:

The first line of input contains a number t, which means there are t cases of the test data

for each test case, the first line contain a number n, indicate the number of oranges

the second line contains n numbers, Wi, indicate the weight of each orange

n is between 1 and 100, inclusive、 Wi is between 0 and 2000, inclusive、 the sum of Wi is equal or less than 2000

输出:

For each test case, output the maximum weight in one side of Carrying pole、 If you can't carry any orange, output -1、 Output format is shown in Sample Output

样例输入:

1

5

1 2 3 4 5

样例输出:

Case 1: 7

#include <cstdio>

#include <cstring>

using namespace std;

 

int max(int a,int b)    {return (a>=b)?a:b;}

int min(int a,int b)    {return (a<=b)?a:b;}

 

int main()

{

    const int MAX_SUM_WEIGHT=2000;

    int dp[2][MAX_SUM_WEIGHT/2+1],op,np;

    const int MAX_SIZE=100;

    int w[MAX_SIZE];

    int tc,tcase=1;

    int n;

    scanf("%d",&tc);

    while(tc--)

    {

 int i,j;

 bool has_zero=false;

 scanf("%d",&n);

 j=0;

 for(i=0;i<n;i++)

 {

     scanf("%d",&w[i]);

     j+=w[i];

 }

  

 op=0;

 np=1;

 int lmt=j/2+1;

 memset(dp[op],-1,lmt*sizeof(int));

 dp[op][0]=0;

 for(i=0;i<n;i++)

 {

     if(w[i]==0)

     {

  has_zero=true;

  continue;

     }

     memcpy(dp[np],dp[op],lmt*sizeof(int));

     //for(j=0;j<lmt;j++) dp[np][j]=dp[op][j];

     for(j=0;j<lmt;j++)

     {

  if(dp[op][j]<0)  continue;

  if(j+w[i]<lmt)   dp[np][j+w[i]]=max(dp[np][j+w[i]],dp[op][j]);

  if(j-w[i]>=0)    dp[np][j-w[i]]=max(dp[np][j-w[i]],dp[op][j]+w[i]);

  else     dp[np][w[i]-j]=max(dp[np][w[i]-j],dp[op][j]+j);

     }

     op=np;

     np=1-op;

 }

  

 printf("Case %d: %d\n",tcase++,((dp[op][0]>0)?dp[op][0]:(has_zero?0:-1)));

    }

    return 0;

}

 

/*

5

1 2 3 4 5

 

7

 

10

50 9 8 8 8 8 8 8 8 3

 

59

 

12

8 8 50 8 8 3 8 8 8 9 51 7

 

84

*/

102、 题目描述:

辰辰是个很有潜能、天资聪颖的孩子,他的梦想是称为世界上最伟大的医师。

为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了1个难题。

医师将他带到个到处都是草药的山洞里对他说:

“孩子,这个山洞里有1些不同的草药,采每1株都需要1些时间,每1株也有它自身的价值。

我会给你1段时间,在这段时间里,你可以采到1些草药。如果你是1个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

输入:

输入的第1行有两个整数T1 <= T <= 1000)和M1 <= M <= 100),T代表总共能够用来采药的时间,M代表山洞里的草药的数目。

接下来的M行每行包括两个在1100之间(包括1100)的的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出:

可能有多组测试数据,对于每组数据,

输出只包括1行,这1行只包含1个整数,表示在规定的时间内,可以采到的草药的最大总价值。 

样例输入:

70 3

71 100

69 1

1 2

样例输出:

3

#include<stdioh>

#include<stdlibh>

int max2int(int a,int b)

{

    if(a>b)

    {

 return a;

    }

    return b;

}

int getmaxvalue(int* the_time,int* values,int num,int totaltime)

{

    /*输入 the_time是每1项的时间

 * values是每1项的价值

 * num是总的项数

 * totaltime是最大可用时间

 *

 * 输出为能够取到的最大值

 * */

    int* ans=(int*)malloc((totaltime+1)*sizeof(int));

    int i,j,maxvalue;

    for(i=0;i!=(totaltime+1);i++)

    {

 ans[i]=0;

    }

    for(i=0;i!=num;i++)

    {

 for(j=totaltime;j>=0;j--)

 {

     if(j-the_time[i]>=0)

     {

  ans[j]=max2int(ans[j],ans[j-the_time[i]]+values[i]);

     }

 }

    }

    maxvalue=ans[totaltime];

    free(ans);

    return maxvalue;

}

int main(int argc,char** argv)

{

    int *the_time,*values,t,m,i;

    while(scanf("%d%d",&t,&m)!=EOF)

    {

 the_time=(int*)malloc(m*sizeof(int));

 values=(int*)malloc(m*sizeof(int));

  

 for(i=0;i<m;i++)

 {

     scanf("%d%d",the_time+i,values+i);

 }

 printf("%d\n",getmaxvalue(the_time,values,m,t));

 free(the_time);

 free(values);

    }

    return 0;

}

103、 题目描述:

Before ACM can do anything, a budget must be prepared and the necessary financial support obtained、 The main income for this action comes from Irreversibly Bound Money (IBM)、 The idea behind is simple、 Whenever some ACM member has any small money, he takes all the coins and throws them into a piggy-bank、 You know that this process is irreversible, the coins cannot be removed without breaking the pig、 After a sufficiently long time, there should be enough cash in the piggy-bank to pay everything that needs to be paid、 

But there is a big problem with piggy-banks、 It is not possible to determine how much money is inside、 So we might break the pig into pieces only to find out that there is not enough money、 Clearly, we want to avoid this unpleasant situation、 The only possibility is to weigh the piggy-bank and try to guess how many coins are inside、 Assume that we are able to determine the weight of the pig exactly and that we know the weights of all coins of a given currency、 Then there is some minimum amount of money in the piggy-bank that we can guarantee、 Your task is to find out this worst case and determine the minimum amount of cash inside the piggy-bank、 We need your help、 No more prematurely broken pigs!

输入:

The input consists of T test cases、 The number of them (T) is given on the first line of the input file、 Each test case begins with a line containing two integers E and F、 They indicate the weight of an empty pig and of the pig filled with coins、 Both weights are given in grams、 No pig will weigh more than 10 kg, that means 1 <= E <= F <= 10000、 On the second line of each test case, there is an integer number N (1 <= N <= 500) that gives the number of various coins used in the given currency、 Following this are exactly N lines, each specifying one coin type、 These lines contain two integers each, Pand W (1 <= P <= 50000, 1 <= W <=10000)、 P is the value of the coin in monetary units, W is it's weight in grams

输出:

Print exactly one line of output for each test case、 The line must contain the sentence "The minimum amount of money in the piggy-bank is X" where X is the minimum amount of money that can be achieved using coins with the given total weight、 If the weight cannot be reached exactly, print a line "This is impossible"

样例输入:

3

10 110

2

1 1

30 50

10 110

2

1 1

50 30

1 6

2

10 3

20 4

样例输出:

The minimum amount of money in the piggy-bank is 60

The minimum amount of money in the piggy-bank is 100

This is impossible

#include <cstdio>

#include <cstring>

const long long  INF = 999999999;

const int MAX = 501;

const int MAXWEIGH = 10004;

int T,E,F,N,P,W,values[MAX],weigh[MAX];

long long dp[MAXWEIGH];

long long min(long long a, long long b)

{

    return a > b ? b : a;

}

int main()

{

    //freopen("intxt", "r", stdin);

    scanf("%d", &T);

    while (T-- > 0)

    {

 memset(values, 0, sizeof(int)*MAX);

 memset(weigh, 0, sizeof(int)*MAX);

 for (int i = 0; i < MAXWEIGH; ++i) dp[i] = INF;

 scanf("%d %d", &E, &F);

 scanf("%d", &N);

 for (int i = 0; i < N; ++i) scanf("%d %d", &values[i],&weigh[i]);

 //algorithm start

 int need = F - E;

 for (int i = 1; i <= N; ++i)

 {

     dp[0] = 0;

     for (int j = weigh[i-1]; j <= need; ++j)

     {

  dp[j] = min(dp[j], dp[j - weigh[i - 1]] + values[i - 1]);

     }

 }

 if (dp[need] < INF)

     printf("The minimum amount of money in the piggy-bank is %lld\n", dp[need]);

 else printf("This is impossible\n");

    }

    //fclose(stdin);

    return 0;

}

104、 题目描述:

为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购1些粮食支援灾区,现在假设你1共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。请问:你用有限的资金最多能采购多少公斤粮食呢?

输入:

输入数据首先包含1个正整数C,表示有C组测试用例,每组测试用例的第1行是两个整数nm(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数phc(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。

输出:

对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占1行。

样例输入:

1

8 2

2 100 4

4 100 2

样例输出:

400

#include <cstdio>

#include <stringh>

using namespace std;

 

int cs,M,N;

int rice[105][3];

int cost[105];

 

 

void package(int m,int w)

{

    for (int i=N;i>=m;--i)

    {

 cost[i] = cost[i-m]+w>cost[i]?cost[i-m]+w:cost[i];

    }

}

 

int main(void)

{

    scanf("%d",&cs);

    while (cs--)

    {

 memset(cost,0,sizeof(cost));

 scanf("%d%d",&N,&M);

 for (int i=0;i<M;++i)

 {

     scanf("%d%d%d",&rice[i][0],&rice[i][1],&rice[i][2]);

 }

 for (int i=0;i<M;++i)

 {

     for (int j=0;j<rice[i][2];++j)

     {

  package(rice[i][0],rice[i][1]);

     }

 }

 printf("%d\n",cost[N]);

    }

    return 0;

}

105、 题目描述:

给定1个短string(不含空格),再给定若干string,在这些string中删除所含有的短string

输入:

输入只有1组数据。

输入1个短string(不含空格),再输入若干string直到文件结束为止。

输出:

删除输入的短string(不区分大小写)并去掉空格,输出。

样例输入:

in

#include 

int main()

{

printf(" Hi ");

}

样例输出:

#clude

tma()

{

prtf("Hi");

}

#include<iostream>

#include<string>

using namespace std;

int main()

{

string s1;

char s[1000];

cin>>s1;

int j;

string s2;

string::iterator i;

cinignore();

while(cingetline(s,1000))

{

s2=s;

while(s2find(s1)!=string::npos)

{

i=s2begin()+s2find(s1);

s2erase(i,i+s1length());

}

while(s2find(' ')!=string::npos)

{

i=s2begin()+s2find(' ');

s2erase(i);

}

cout<<s2<<endl;

}

return 0;

}

106、 题目描述:

输入1string,以回车结束(string长度<=100)。该string由若干个单词组成,单词之间用1个空格隔开,所有单词区分大小写。现需要将其中的某个单词替换成另1个单词,并输出替换之后的string

输入:

多组数据。每组数据输入包括3行,

1行是包含多个单词的string s

2行是待替换的单词a(长度<=100)

3行是a将被替换的单词b(长度<=100)

s, a, b 最前面和最后面都没有空格、

输出:

每个测试数据输出只有 行,

s中所有单词a替换成b之后的string

样例输入:

You want someone to help you

You

I

样例输出:

I want someone to help you

#include<iostream>

#include<fstream>

#include<string>

#include<algorithm>

using namespace std;

int main()

{

 string a,b,s;

// fstream cin("1111txt");

 while (getline(cin,s))

 {

  cin>>a>>b;

  string::size_type pos=0;

  while((pos=sfind(a,pos))!=string::npos)

  {

   if (pos==0)

   {

    sreplace(pos,asize(),b);

    pos++;

   }

   else if (s[pos-1]==' '&&(s[pos+asize()]==' '||s[pos+asize()]=='\0'))

   {

    sreplace(pos,asize(),b);

    pos++;

   }

   else

   {

    pos++;

   }

  }

  cout<<s<<endl;

  cinignore();

 }

 return 0;

}

107、 题目描述:

输入strings和字符c,要求去掉s中所有的c字符,并输出结果。

输入:

测试数据有多组,每组输入strings和字符c

输出:

对于每组输入,输出去除c字符后的结果。

样例输入:

heallo

a

样例输出:

Hello

#include <stdioh>

#include <stringh>

int main()

{

 char str[1000000],ch,ch1;

 int len,i;

 while (gets(str))

 {

  scanf("%c",&ch);

  len = strlen(str);

  for (i=0;i<len;i++)

  {

   if (str[i] != ch)

    printf("%c",str[i]);

  }

  printf("\n");

  ch1 = getchar();

 }

 return 0;

}

108、 题目描述:

对给定的string(只包含'z','o','j'三种字符),判断他是否能AC

是否AC的要求如下:

1、 zojAC;

2、 若string形式为xzojx,则也能AC,其中x可以是N'o' 或者为空;

3、 若azbjc AC,则azbojac也能AC,其中a,b,cN'o'或者为空;

输入:

输入包含多组测试用例,每行有1个只包含'z','o','j'三种字符的stringstring长度小于等于1000

输出:

对于给定的string,如果能AC则请输出stringAccepted”,否则请输出“Wrong Answer”。

样例输入:

zoj

ozojo

ozoojoo

oozoojoooo

zooj

ozojo

oooozojo

zojoooo

样例输出:

Accepted

Accepted

Accepted

Accepted

Accepted

Accepted

Wrong Answer

Wrong Answer

#include <iostream>

using namespace std;

int main() {

 string str;

 while(cin >> str){

  int count1 = 0, count2 = 0;

  const char *pchar = strc_str();

  int i = 0;

  while(pchar[i] == 'o'){

   count1++;

   i++;

  }

  if(pchar[i] != 'z'){

   cout << "Wrong Answer" <<endl;

   continue;

  }

  i++;

  if(pchar[i] != 'o'){

   cout << "Wrong Answer" <<endl;

   continue;

  }

  while(pchar[i] == 'o'){

   i++;

  }

  if(pchar[i] != 'j'){

   cout << "Wrong Answer" <<endl;

   continue;

  }

  i++;

  while(pchar[i] == 'o'){

   count2++;

   i++;

  }

  if(count1 <= count2 && pchar[i] == 0){

   if(count1 ==0 && count2 != 0){

    cout << "Wrong Answer" <<endl;

    continue;

   }

   cout << "Accepted" <<endl;

  }

  else{

   cout << "Wrong Answer" <<endl;

  }

 }

 return 0;

}

109、 题目描述:

按要求,给国家进行排名。

输入:

有多组数据。

1行给出国家数N,要求排名的国家数M,国家号从0N-1

2行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。

接下来1行给出M个国家号。

输出:

排序有4种方式金牌总数 奖牌总数 金牌人口比例 奖牌人口比例 

对每个国家给出最佳排名排名方式 和 最终排名

格式为排名:排名方式

如果有相同的最终排名,则输出排名方式最小的那种排名,对于排名方式,金牌总数 奖牌总数 金牌人口比例 奖牌人口比例 

如果有并列排名的情况,即如果出现金牌总数为 100,90,90,80、则排名为1,2,2,4

每组数据后加1个空行。

样例输入:

4 4

4 8 1

6 6 2

4 8 2

2 12 4

0 1 2 3

4 2

8 10 1

8 11 2

8 12 3

8 13 4

0 3

样例输出:

1:3

1:1

2:1

1:2

1:1

1:1

#include <iostream>

#include <algorithm>

#include <cstdio>

#include <cstring>

using namespace std;

const int Maxn = 100000;

struct Con{

 double God,Pri,Peo;

 double Godper,Peoper;

 int id;

}P[Maxn],rp[Maxn];

int rank[Maxn];

int N,M;

bool cmp(const Con a, const Con b)

{

 return aPeoper>bPeoper;

}

bool cmp1(const Con a, const Con b)

{

 return aGodper>bGodper;

}

bool cmp2(const Con a, const Con b)

{

 return aPri>bPri;

}

bool cmp3(const Con a, const Con b)

{

 return aGod>bGod;

}

int main()

{

 int i,index[Maxn],j;

 int bet,way;

 while(scanf("%d%d",&N,&M)!=EOF)

 {

  for(i = 0; i<N; i++)

  {

   cin>>rp[i]God>>rp[i]Pri>>rp[i]Peo;

   rp[i]Godper = rp[i]God/rp[i]Peo;

   rp[i]Peoper = rp[i]Pri/rp[i]Peo;

  }

  int r = 0;

  for(i = 0; i<M; i++)

  {

   cin>>index[i];

   P[r] = rp[index[i]];

   P[r++]id = index[i];

  }

  for(i = 0; i<M; i++)

  {

   sort(P,P+M,cmp3);

   rank[0] = 1;

   for(j = 1; j<M; j++)

   if(P[j]God == P[j-1]God)rank[j] = rank[j-1];

   else rank[j] = j+1;

   for(j = 0; j<M; j++)

    if(P[j]id == index[i])

    { 

      bet = rank[j];

      way = 1;

      break;

    }

   sort(P,P+M,cmp2);

   rank[0] = 1;

   for(j = 1; j<M; j++)

   if(P[j]Pri == P[j-1]Pri)rank[j] = rank[j-1];

   else rank[j] = j+1;

   for(j = 0; j<M; j++)

    if(P[j]id == index[i])

    { 

     if(rank[j]<bet)

     {

      bet = rank[j];

      way = 2;

     }

     break;

    }  

   sort(P,P+M,cmp1);

   rank[0] = 1;

   for(j = 1; j<M; j++)

   if(P[j]Godper == P[j-1]Godper)rank[j] = rank[j-1];

   else rank[j] = j+1;

   for(j = 0; j<M; j++)

    if(P[j]id == index[i])

    { 

     if(rank[j]<bet)

     {

      bet = rank[j];

      way = 3;

     }

     break;

    }

   sort(P,P+M,cmp);

   rank[0] = 1;

   for(j = 1; j<M; j++)

   if(P[j]Peoper == P[j-1]Peoper)rank[j] = rank[j-1];

   else rank[j] = j+1;

   for(j = 0; j<M; j++)

    if(P[j]id == index[i])

    {

     if(rank[j]<bet)

     {

      bet = rank[j];

      way = 4;

     }

     break;

    }

   printf("%d:%d\n",bet,way);

  }

  printf("\n");

  

 }

 return 0;

}

#include<stdioh>

#include<algorithm>

using namespace std;

 

#define N 300 //根据实际情况定义大小,全世界只有200多个国家和地区

 

struct Country { //国家结构体,存储相关信息

    int id;

    int gold;

    int medal;

    int population;

}country1[N], country2[N];

 

bool cmp1(Country a, Country b) { //按金牌数降序排列

    return agold > bgold;

}

 

bool cmp2(Country a, Country b) {

    return amedal > bmedal;

}

 

//注意定义时gold,medalpopulation都是整数,因此求人均时必须先化为浮点数,

//否则会出现本来人际不同,但取整后相同的情况

bool cmp3(Country a, Country b) {

    return agold*10/apopulation > bgold*10/bpopulation;

}

 

bool cmp4(Country a, Country b) {

    return amedal*10/apopulation > bmedal*10/bpopulation;

}

 

int rankid[N]; //存放需要排名的国家号

int rankc[N]; //存放需要排名的国家的最好名次

int rankway[N]; //存放需要排名的国家的最好名次对应的排列方式

 

int main() {

    //freopen("intxt","r",stdin);

    int n, m;

    while(scanf("%d %d",&n,&m)!=EOF) {

 int i, j, k;

 for(i=0; i<n; i++) {

     country1[i]id = i; //按输入顺序给国家编号,从0开始

     scanf("%d %d %d",&country1[i]gold,&country1[i]medal,&country1[i]population);

 }

 for(i=0; i<m; i++) { //记录需要排名的国家号

     scanf("%d",&rankid[i]);

 }

 for(i=0; i<m; i++) { //将需要排名的国家存放到另外1个结构体数组,方便排序

     for(j=0; j<n; j++) {

  if(rankid[i] == country1[j]id) {

      country2[i] = country1[j];

      break;

  }

     }

 }

 

 sort(country2,country2+m,cmp1); //按金牌数降序排列

 for(i=0; i<m; i++) {

     for(j=0; j<m; j++) { //遍历已排好序的结构体数组,找到当前国家的名次

  if(rankid[i] == country2[j]id) { 

      for(k=0; k<m; k++) {

   if(country2[k]gold == country2[j]gold) { //处理同名次的情况,以第1次出现为准

       rankc[i] = k+1; //暂存当前最优名次

       rankway[i] = 1; //暂存对应的排序方式

       break;

   }

      }

      break;

  }  

     }

 }

 

 sort(country2,country2+m,cmp2);

 for(i=0; i<m; i++) {

     for(j=0; j<m; j++) {

  if(rankid[i] == country2[j]id) {

      for(k=0; k<m; k++) {

   if(country2[k]medal == country2[j]medal) {

       if(k+1 < rankc[i]) { //若此时名次更好,则更新最优名次和对应的排序方式

    rankc[i] = k+1;  //因为是按排序方式由小到大的顺序处理的,所以无需考虑同名次时更新排序方式

    rankway[i] = 2;

       }

       break;

   }

      }        

      break;

  }

     }

 }

 

 sort(country2,country2+m,cmp3);

 for(i=0; i<m; i++) {

     for(j=0; j<m; j++) {

  if(rankid[i] == country2[j]id) {

      for(k=0; k<m; k++) {

   if(country2[k]gold*10/country2[k]population == country2[j]gold*10/country2[j]population) {

       if(k+1 < rankc[i]) {

    rankc[i] = k+1;

    rankway[i] = 3;

       }

       break;

   }

      }        

      break;

  }

     }

 }

 

 sort(country2,country2+m,cmp4);

 for(i=0; i<m; i++) {

     for(j=0; j<m; j++) {

  if(rankid[i] == country2[j]id) {

      for(k=0; k<m; k++) {

   if(country2[k]medal*10/country2[k]population == country2[j]medal*10/country2[j]population) {

       if(k+1 < rankc[i]) {

    rankc[i] = k+1;

    rankway[i] = 4;

       }

       break;

   }

      }        

      break;

  }

     }

 }

 

 for(i=0; i<m; i++) { //按照需要排序国家的国家号从小到大输出对应信息

     printf("%d:%d\n",rankc[i],rankway[i]);

 }

 printf("\n");

    }

 

    return 0;

}

110、 题目描述:

读入两个小于100的正整数AB,计算A+B

需要注意的是:AB的每1位数字由对应的英文单词给出、

输入:

测试输入包含若干测试用例,每个测试用例占1,格式为"A + B =",相邻两string1个空格间隔、当AB同时为0时输入结束,相应的结果不要输出、

输出:

对每个测试用例输出1,A+B的值、

样例输入:

one + two =

three four + five six =

zero seven + eight nine =

zero + zero =

样例输出:

3

90

96

#include <iostream>

#include <string>

#include <map>

using namespace std;

string str;

string Num[10] = {"zero","one","two","three","four","five","six","seven","eight","nine"};

map<string, int>Q;

void init()

{

 for(int i = 0; i<10; i++)

  Q[Num[i]] = i;

}

int main()

{

 int i,a,b,len,flag;

 //freopen("intxt","r",stdin);

 init();

 while(getline(cin,str))

 {

  a = b = flag = 0;

  len = strsize();

  for(i = 0; i<len; i++)

  {

   string op = "";

   while(str[i]!=' '&&i<len)

   {

    op+=str[i];

    i++;

   }

   if(op[0] == '+'||op[0] == '=')

   {

    flag = 1;

    continue;

   }

   if(!flag)a = a*10+Q[op];

   else b = b*10+Q[op];

  }

  if(a == 0 && b == 0)break;

  else 

   cout<<a+b<<endl;

 }

 return 0; 

}

111、 题目描述:

    给定K个整数的序列{ N1, N2, 、、、, NK },其任意连续子序列可表示为{ Ni, Ni+1, 、、、, Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的1个,示例给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和为20。现在增加1个要求,即还需要输出该子序列的第1个和最后1个元素。

输入:

    测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( K< 10000 ),第2行给出K个整数,中间用空格分隔。当K0时,输入结束,该用例不被处理。

输出:

    对每个测试用例,在1行里输出最大和、最大连续子序列的第1个和最后1个元素,中间用空格分隔。如果最大连续子序列不唯1,则输出序号ij最小的那个(如输入样例的第23组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。

样例输入:

6

-2 11 -4 13 -5 -2

10

-10 1 2 3 4 -5 -23 3 7 -21

6

5 -8 3 2 5 0

1

10

3

-1 -5 -2

3

-1 0 -2

0

样例输出:

20 11 13

10 1 4

10 3 5

10 10 10

0 -1 -2

0 0 0

#include<stdioh>

#define Max 10000

int main(){

 int maxsofar;

 int maxendinghere;

 int begin,end,temp;

 int x[Max];

 int i,n;

 int count;

 while(scanf("%d",&n),n>0){

  for(i=0;i<n;i++)

   scanf("%d",&x[i]);

  count = 0;

  maxsofar = maxendinghere = 0;

  begin = end = temp = 0;

  for(i=0;i<n;i++){

   if(x[i]<0) count++;

   maxendinghere += x[i];

   if(maxendinghere<=0){

    maxendinghere = 0;

    temp = i+1;

   }

   if(maxendinghere>maxsofar){

    maxsofar = maxendinghere;

    begin = temp;

    end = i;

   }

   if(maxendinghere==0&&maxsofar==0&&x[i]==0)

    end = begin = i;

  }

  if(count==n) printf("0 %d %d\n",x[0],x[n-1]);

  else

   printf("%d %d %d\n",maxsofar,x[begin],x[end]);

 }

}

112、 题目描述:

    每天第1个到机房的人要将门打开,最后1个离开的人要将门关好。现有1堆杂乱的机房签到、签离记录,请根据记录找出当天开门和关门的人。

输入:

    测试输入的第1行给出记录的总天数N ( N> 0 ),下面列出了N天的记录。 

    每天的记录在第1行给出记录的条目数M (M > 0 ),下面是M行,每行的格式为 

    证件号码 签到时间 签离时间 

    其中时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15string

输出:

    对每1天的记录输出1行,即当天开门和关门人的证件号码,中间用1空格分隔。 

    注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,且没有多人同时签到或者签离的情况。

样例输入:

3

1

ME3021112225321 00:00:00 23:59:59

2

EE301218 08:05:35 20:56:35

MA301134 12:35:45 21:40:42

3

CS301111 15:30:28 17:00:10

SC3021234 08:00:00 11:25:25

CS301133 21:45:00 21:58:40

样例输出:

ME3021112225321 ME3021112225321

EE301218 MA301134

SC3021234 CS301133

#include<stdioh>

#include<stringh>

int main()

{

 int m,n,i,j;

 char id[16],a[16],b[16];

 int eh,em,es,lh,lm,ls;

 int ehh,emm,ess,lhh,lmm,lss;

 while(scanf("%d",&n)!=EOF)

 {

  if(n<=0)

  {

   return 0;

  }

  for(i=0;i<n;i++)

  {

   scanf("%d",&m);

   if(m<=0)

   {

    return 0;

   }

   scanf("%s %d:%d:%d %d:%d:%d",id,&ehh,&emm,&ess,&lhh,&lmm,&lss);

   eh=ehh;em=emm;es=ess;

   lh=lhh;lm=lmm;ls=lss;

   strcpy(a,id);strcpy(b,id);

   for(j=1;j<m;j++)

   {

    scanf("%s %d:%d:%d %d:%d:%d",id,&ehh,&emm,&ess,&lhh,&lmm,&lss);

    if((ehh<eh)||((ehh==eh)&&(emm<em))||((ehh==eh)&&(emm==em)&&(ess<es)))

    {

     strcpy(a,id);

    }

    if((lhh>lh)||((lhh==lh)&&(lmm>lm))||((lhh==lh)&&(lmm==lm)&&(lss>ls)))

    {

     strcpy(b,id);

    }

   }

   printf("%s %s\n",a,b);

  }

 }

 return 0;

}

113、 题目描述:

    今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的考生,并将他们的成绩按降序打印。

输入:

    测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N < 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;2行排序给出第1题至第M题的正整数分值;以下N行,每行给出1名考生的准考证号(长度不超过20string)、该生解决的题目总数m、以及这m道题的题号(题目号由1M)。 

    当读入的考生人数为0时,输入结束,该场考试不予处理。

输出:

    对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考号的升序输出。

样例输入:

4 5 25

10 10 12 13 15

CS004 3 5 1 3

CS003 5 2 4 1 3 5

CS002 2 1 2

CS001 3 2 3 5

1 2 40

10 30

CS001 1 2

2 3 20

10 10 10

CS000000000000000001 0

CS000000000000000002 2 1 2

0

样例输出:

3

CS003 60

CS001 37

CS004 37

0

1

CS000000000000000002 20

#include <iostream>

#include <cstdio>

#include <algorithm>

#include <string>

using namespace std;

const int Maxn = 1005;

struct Rank{

 string id;

 int sc;

}P[Maxn];

int Op[20];

bool cmp(const Rank a, const Rank b)

{

 if(asc>bsc)return true;

 else if(asc == bsc && aid<bid)return true;

 return false;

}

int main()

{

 int N,M,G;

 int i,n,ans,a;

 string str;

 while(cin>>N)

 {

  if(N == 0)break;

  cin>>M>>G;

  for(i = 1; i<=M; i++)

   cin>>Op[i];

  ans = 0;

  for(i = 0; i<N; i++)

  {

   cin>>str;

   cin>>n;

   int sum = 0;

   while(n--)

   {

    cin>>a;

    sum+=Op[a];

   }

   if(sum>=G)

   {

    P[ans]id = str;

    P[ans++]sc = sum;

   }

  }

  sort(P,P+ans,cmp);

  cout<<ans<<endl;

  for(i = 0; i<ans; i++)

   cout<<P[i]id<<' '<<P[i]sc<<endl; 

 }

 return 0;

}

114、 题目描述:

    读入两个不超过25位的火星正整数AB,计算A+B。需要注意的是:在火星上,整数不是单1进制的,第n位的进制就是第n个素数。示例:地球上的10进制数2,在火星上记为“1,0”,因为火星个位数是2进制的;地球上的10进制数38,在火星上记为“1,1,1,0”,因为火星个位数是2进制的,十位数是3进制的,百位数是5进制的,千位数是7进制的……

输入:

    测试输入包含若干测试用例,每个测试用例占1行,包含两个火星正整数AB,火星整数的相邻两位数用逗号分隔,AB之间有1个空格间隔。当AB0时输入结束,相应的结果不要输出。

输出:

    对每个测试用例输出1行,即火星表示法的A+B的值。

样例输入:

1,0 2,1

4,2,0 1,2,0

1 10,6,4,2,1

0 0

样例输出:

1,0,1

1,1,1,0

1,0,0,0,0,0

#include<iostream>

using namespace std;

void change(char str[],int num[],int &j)//将字符转换为数字

{

int i=0;

    j=0;

while(str[i]!='\0')

{

if(str[i]<='9'&&str[i]>='0')

{

num[j]=num[j]*10+str[i]-'0';

i++;

}

else {i++;j++;}

}

j++;

}

void reve(int r[],int ri)//为了方便运算 逆转数组

{

int i;

ri=ri-1;

for(i=0;i<=ri/2;i++)

{

int er=r[i];

r[i]=r[ri-i];

r[ri-i]=er;

}

}

int main()

 int i;

 int j;

 i=5;

 static int X[50];

 X[0]=2;

 X[1]=3;

 int v=2;

 while(1)

 {

 int temp=1;

 for(j=2;j<i/2;j++)if(i%j==0)temp=0;

 if(temp==1){X[v]=i;v++;}

 if(v==49)break;

 i++;

 }//求素数存于X数组中

 char A[100];

 static int a[50];

 char B[100];

 static int b[50];

 static int ab[50];

 int ai;

 int bi;

 while(cin>>A>>B)//

 {

 if(A[0]=='0'&&B[0]=='0')break;

 for(i=0;i<50;i++)a[i]=b[i]=ab[i]=0;//所有数组赋值 这里系统有1个小BUG 如果直接static初始化数组会悲剧

 change(A,a,ai);//A转化为数字

 change(B,b,bi);//

    reve(a,ai);//反转A的数组a

 reve(b,bi);//

 int C=0;//c用来保存进位 初值为0

 for(i=0;i<=29;i++)//两组数求和 当超过进制时 进位

 {

 ab[i]=(a[i]+b[i]+C)%X[i];

 C=(C+a[i]+b[i]-ab[i])/X[i];

 }

    reve(ab,50);//上面求得的答案逆序存在ab数组中 通过逆序再反倒过来

 i=0;

 while(ab[i]==0)i++;//找到储存结果的起始点

    while(i<50)//循环输出答案

 {

 cout<<ab[i];

 if(i!=49)cout<<",";//最后1个数字的时候不用输出,号

 i++;

 }

 cout<<endl;//记得结束的时候换行

 }

return 0;

}

115、 题目描述:

    给定1系列2维平面点的坐标(x, y),其中xy均为整数,要求用1个最小的长方形框将所有点框在内。长方形框的边分别平行于xy坐标轴,点落在边上也算是被框在内。

输入:

    测试输入包含若干测试用例,每个测试用例由1系列坐标组成,每对坐标占1行,其中|x||y|小于 231;1坐标标志着1个测试用例的结束。注意(0, 0)不作为任何1个测试用例里面的点。1个没有点的测试用例标志着整个输入的结束。

输出:

    对每个测试用例,在1行内输出2对整数,其间用1个空格隔开。第1对整数是长方形框左下角的坐标,第2对整数是长方形框右上角的坐标。

样例输入:

12 56

23 56

13 10

0 0

12 34

0 0

0 0

样例输出:

12 10 23 56

12 34 12 34

#include<stdioh>

int main()

{

 int x,y;

 int minx,miny,maxx,maxy;

 while(scanf("%d %d",&x,&y)&&(x!=0||y!=0))

 {

  minx=256,miny=256,maxx=-256,maxy=-256;

  while(x!=0||y!=0)

  {

   if(x<minx)

    minx=x;

   if(y<miny)

    miny=y;

   if(x>maxx)

    maxx=x;

   if(y>maxy)

    maxy=y;

   scanf("%d %d",&x,&y);

  }

  printf("%d %d %d %d\n",minx,miny,maxx,maxy);

 }

return 0;

}

116、 题目描述:

    统计1个给定string中指定的字符出现的次数。

输入:

    测试输入包含若干测试用例,每个测试用例包含2行,第1行为1个长度不超过5string,第2行为1个长度不超过80string。注意这里的string包含空格,即空格也可能是要求被统计的字符之1。当读到'#'时输入结束,相应的结果不要输出。

输出:

    对每个测试用例,统计第1行中string的每个字符在第2string中出现的次数,按如下格式输出:

    c0 n0

    c1 n1

    c2 n2

    、、、 

    其中ci是第1行中第i个字符,nici出现的次数。

样例输入:

I

THIS IS A TEST

i ng

this is a long test string

#

样例输出:

I 2

i 3

  5

n 2

g 2

#include<iostream>

#include<string>

using  namespace std;

int main()

{

 string pa,line;

 int i,j;

 while(getline(cin,pa)&&pa!="#")

 {

  getline(cin,line);

  int co[5]={0};

  for(i=0;i<linesize();i++)

  {

   for(j=0;j<pasize()&&pa[j]!=line[i];j++);

     co[j]+=j<pasize();

  } 

  for(i=0;i<pasize();i++)

   {

   cout<<pa[i]<<" "<<co[i]<<endl;

  }

 }

 return 0;

}

117、 题目描述:

    现有公园游船租赁处请你编写1个租船管理系统。当游客租船时,管理员输入船号并按下S键,系统开始计时;当游客还船时,管理员输入船号并按下E键,系统结束计时。船号为不超过100的正整数。当管理员将0作为船号输入时,表示1天租船工作结束,系统应输出当天的游客租船次数和平均租船时间。

    注意:由于线路偶尔会有故障,可能出现不完整的纪录,即只有租船没有还船,或者只有还船没有租船的纪录,系统应能自动忽略这种无效纪录。

输入:

    测试输入包含若干测试用例,每个测试用例为1整天的租船纪录,格式为:

    船号(1~100) 键值(SE) 发生时间(小时:分钟)

    每1天的纪录保证按时间递增的顺序给出。当读到船号为-1时,全部输入结束,相应的结果不要输出。

输出:

    对每个测试用例输出1行,即当天的游客租船次数和平均租船时间(以分钟为单位的精确到个位的整数时间)。

样例输入:

1 S 08:10

2 S 08:35

1 E 10:00

2 E 13:16

0 S 17:00

0 S 17:00

3 E 08:10

1 S 08:20

2 S 09:00

1 E 09:20

0 E 17:00

-1

样例输出:

2 196

0 0

1 60

#include<stdioh>

struct{

 int flag; /*标记船有无被借出,借出为1,否则为0*/ 

 int time;

}boat[101];

int main(){

  int hour,minute,number,temptime;/*number为船号*/ 

  char S_E;/*标记是租借还是归还*/ 

  while(scanf("%d",&number) != EOF){

  if(number == -1) return 0;

   int count = 0;

   double totaltime = 0;

   /*处理number不为0的情况*/ 

   while(number){

    scanf(" %c %d:%d",&S_E,&hour,&minute);

    temptime = hour * 60 + minute;

    if(S_E == 'S'){/*如果是借出则将借出的该船标记置1,*/ 

     boat[number]flag = 1;

     boat[number]time = temptime;

    }

    else{

     if(boat[number]flag){/*如果是归还之前已借出的该船 ,则记下时间差值,数目加1,并将标志置0*/ 

      totaltime += temptime - boat[number]time;

      count ++;

      boat[number]flag = 0;

     }

    }

    scanf("%d",&number);

   }

   /*如果船号为0,依然正常输入各值,但此时不做处理*/ 

   scanf(" %c %d:%d",&S_E,&hour,&minute);

   if(count)  totaltime = totaltime/count;

     printf ("%d %0lf\n",count,totaltime);

 }

 return 0;

}

119、 题目描述:

    现有1笔经费可以报销1定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的1堆发票中找出可以报销的、不超过给定额度的最大报销额。

输入:

    测试输入包含若干测试用例。每个测试用例的第1行包含两个正数 和 N,其中 是给定的报销额度,NN<=30)是发票张数。随后是 行输入,每行的格式为:

    m Type_1:price_1 Type_2:price_2 、、、 Type_m:price_m

    其中正整数 是这张发票上所开物品的件数,Type_i 和 price_i 是第 项物品的种类和价值。物品种类用1个大写英文字母表示。当N0时,全部输入结束,相应的结果不要输出。

输出:

    对每个测试用例输出1行,即可以报销的最大数额,精确到小数点后2位。

样例输入:

20000 3

2 A:2350 B:10000

1 C:65000

3 A:5999 A:12000 X:1000

120000 2

2 B:60000 A:40000

1 C:20050

120050 3

2 B:60000 A:40000

1 C:20050

1 A:10000

10000 0

样例输出:

12350

100000

120050

#include<iostream>

#include<stdioh>

#include<stringh>

#include<iomanip>

#include<mathh>

using namespace std;

double a[31];

int top;

double max(double x,double y){

   if(x>y)return x;

   else return y;

}

double maxvalue(int k,double left,double Q){//递归求最大报销额 

    //cout<<"left="<<left<<" Q="<<Q<<endl;

    int mark=0;

    double t=0;

    for(int i=k;i<top;i++)

 if(a[i]<=left){

     t=max(maxvalue(i+1,left-a[i],Q),t);

     //cout<<"t="<<t<<endl;

     mark=1;

 }

    if(mark==0)return Q-left;

    else return t;

}     

int main(void){

    double Q,sum,value,total;

    int n,m,mark;

    char c,d;

    while(scanf("%lf%d",&Q,&n)!=EOF){

 if(n==0)break;

 top=0;

 for(int i=0;i<n;i++){

     scanf("%d",&m);

     mark=1;

     sum=0;

     for(int j=0;j<m;j++){

  scanf(" %c:%lf",&c,&value);

  //cout<<"c="<<c<<" value="<<value<<endl;

  if(value>60000||c-'A'>=3)mark=0;

  sum=sum+value;

     }

     if(mark==1&&sum<=100000){

  a[top]=sum;

  //cout<<"top="<<top<<" a["<<top<<"]="<<a[top]<<endl;

  top++;

     }

 }

 printf("%*lf\n",2,maxvalue(0,Q,Q));

    }

    return 0;

}

120、 题目描述:

    欧拉回路是指不令笔离开纸面,可画过图中每条边仅1次,且可以回到起点的1条回路。现给定1个图,问是否存在欧拉回路?

输入:

    测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出1对正整数,分别是该条边直接连通的两个节点的编号(节点从1N编号)。当N0时输入结束。

输出:

    每个测试用例的输出占1行,若欧拉回路存在则输出1,否则输出0

样例输入:

3 3

1 2

1 3

2 3

3 2

1 2

2 3

0

样例输出:

1

0

#include<iostream>

using namespace std;

struct node

{

 int index;

 int rank;

 int key;

 node *p;

};

void make_set(node *n)

{

 n->index=0;

 n->rank=0;

 n->p=n;

}

void union_set(node *n1,node *n2)

{

 if(n1->rank<n2->rank)

  n1->p=n2;

 else

 {

  n2->p=n1;

  if(n1->rank==n2->rank)

   ++n1->rank;

 }

}

node *find_set(node *n)

{

 if(n->p!=n)

  n->p=find_set(n->p);

 return n->p;

}

int main()

{

 int n,m;

 while(cin>>n&&n)

 {

  cin>>m;

  node **a=new node *[n+1];

  for(int i=1;i<=n;++i)

  {

   node *temp=new node;

   temp->key=i;

   make_set(temp);

   a[i]=temp;

  }

  int num=n-1;

  for(int i=1;i<=m;++i)

  {

   int x,y;

   cin>>x>>y;

   ++(a[x]->index);

   ++(a[y]->index);

   if(find_set(a[x])!=find_set(a[y]))

   {

    union_set(a[x],a[y]);

    --num;

   }

  }

  bool b=true;

  for(int i=1;i<=n;++i)

  {

   if((a[i]->index)%2!=0)

   {

    b=false;

    break;

   }

  }

  if(b&&!num)

   cout<<1<<endl;

  else

   cout<<0<<endl;

 }

 return 0;

}

 

3 JAVA方面算法难题(50中等难度)

程序1。

题目:古典问题:有1对兔子,从出生后第3个月起每个月都生1对兔子,小兔子长到第三个月后每个月又生1对兔子,假如兔子都不死,问每个月的兔子总数为多少?   

//这是1个菲波拉契数列问题

public class lianxi01 {

public static void main(String[] args) {

Systemoutprintln("第1个月的兔子对数:    1");

Systemoutprintln("第2个月的兔子对数:    1");

int f1 = 1, f2 = 1, f, M=24;

 for(int i=3; i<=M; i++) {

  f = f2;

  f2 = f1 + f2;

  f1 = f;

  Systemoutprintln("第" + i +"个月的兔子对数: "+f2);

     }

}

}

。程序2。   

题目:判断101-200之间有多少个素数,并输出所有素数。 

程序分析:判断素数的方法:用1个数分别去除2到sqrt(这个数),如果能被整除, 则表明此数不是素数,反之是素数。   

public class lianxi02 {

public static void main(String[] args) {

    int count = 0;

    for(int i=101; i<200; i+=2) {

 boolean b = false;

 for(int j=2; j<=Mathsqrt(i); j++) 

 {

    if(i % j == 0) { b = false; break; } 

     else    { b = true; }

 }

    if(b == true) {count ++;Systemoutprintln(i );}

          }

    Systemoutprintln( "素数个数是: " + count);

}

}

。程序3。   

题目:打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指1个三位数,其各位数字立方和等于该数本身。示例:153是1 "水仙花数 ",因为153=1的三次方+5的三次方+3的三次方。

public class lianxi03 {

public static void main(String[] args) {

 int b1, b2, b3; 

 for(int m=101; m<1000; m++) { 

  b3 = m / 100;

  b2 = m % 100 / 10;

  b1 = m %    10;

  if((b3*b3*b3 + b2*b2*b2 + b1*b1*b1) == m) {

  Systemoutprintln(m+"1个水仙花数"); }

 }

}

}   

。程序4。   

题目:将1个正整数分解质因数。示例:输入90,打印出90=2*3*3*5。   

程序分析:对n进行分解质因数,应先找到1个最小的质数k,然后按下述步骤完成:   

(1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。   

(2)如果n <> k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n,重复执行第1步。   

(3)如果n不能被k整除,则用k+1作为k的值,重复执行第1步。  

import javautil*;

public class lianxi04{ 

    public static void main(String[] args) {

    Scanner s = new Scanner(Systemin);

    Systemoutprint( "请键入1个正整数: "); 

    int    n    = snextInt();

    int k=2; 

    Systemoutprint(n + "=" );

    while(k <= n) {

  if(k == n) {Systemoutprintln(n);break;}

    else if( n % k == 0) {Systemoutprint(k + "*");n = n / k; } 

    else    k++;

       }

 }

    } 

。程序5。   

题目:利用条件运算符的嵌套来完成此题:学习成绩> =90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。   

import javautil*;

public class lianxi05 {

public static void main(String[] args) {

 int x;

 char grade;

 Scanner s = new Scanner(Systemin);

 Systemoutprint( "请输入1个成绩: "); 

 x = snextInt();  

 grade = x >= 90 ? 'A'

   : x >= 60 ? 'B'

   :'C';

    Systemoutprintln("等级为:"+grade);

  

}

。程序6。   

题目:输入两个正整数m和n,求其最大公约数和最小公倍数。   

/**在循环中,只要除数不等于0,用较大数除以较小的数,将小的1个数作为下1轮循环的大数,取得的余数作为下1轮循环的较小的数,如此循环直到较小的数的值为0,返回较大的数,此数即为最大公约数,最小公倍数为两数之积除以最大公约数。* /

import javautil*;

public    class lianxi06 { 

public static void main(String[] args) {

int a ,b,m;

Scanner s = new Scanner(Systemin);

Systemoutprint( "键入1个整数: "); 

a = snextInt();

Systemoutprint( "再键入1个整数: "); 

b = snextInt();

  deff cd = new deff();

  m = cddeff(a,b);

  int n = a * b / m;

  Systemoutprintln("最大公约数: " + m);

  Systemoutprintln("最小公倍数: " + n);

}

class deff{

public int deff(int x, int y) {

 int t;

 if(x < y) {

  t = x;

  x = y;

  y = t;

 }  

 while(y != 0) {

  if(x == y) return x;

  else {

   int k = x % y;

   x = y;

   y = k;

  }

 }

 return x;

}

。程序7。   

题目:输入1行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。   

package WuYang;

import javautil*;

public class lianxi07 {

public static void main(String[] args) {

  int abcCount=0;//英文字母个数

  int spaceCount=0;//空格键个数

  int numCount=0;//数字个数

  int otherCount=0;//其他字符个数

  Scanner scan = new Scanner(Systemin);//扫描器接受控制台的输入信息

  Systemoutprintln("输入1组字符");

String str=scannextLine();//取出控制台的1行信息,也就是你输入的信息

 char[] ch = strtoCharArray();//将取道的string变成1char数组

for(int i=0;i<chlength;i++){

  if(CharacterisLetter(ch[i])){

   //判断是否字母

   abcCount++;

  }

  else if(CharacterisDigit(ch[i])){

   //判断是否数字

   numCount++;

  }

  else if(CharacterisSpaceChar(ch[i])){

   //判断是否空格键

   spaceCount++;

  }

  else{

   //以上都不是则认为是其他字符

   otherCount++;

  }

 }

 Systemoutprintln("字母个数:"+abcCount);

 Systemoutprintln("数字个数:"+numCount);

 Systemoutprintln("空格个数:"+spaceCount);

 Systemoutprintln("其他字符个数:"+otherCount);

 }

}

。程序8。   

题目:求s=a+aa+aaa+aaaa+aa、、、a的值,其中a是1个数字。示例2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。   

import javautil*;

public class lianxi08 {

public static void main(String[] args) {

 long a , b = 0, sum = 0;

 Scanner s = new Scanner(Systemin);

 Systemoutprint("输入数字a的值: ");

 a = snextInt();

 Systemoutprint("输入相加的项数:");

 int n = snextInt();

 int i = 0;

 while(i < n) {

  b = b + a;

  sum = sum + b;

  a = a * 10;

  ++ i;

 }

  Systemoutprintln(sum);

}

。程序9。   

题目:1个数如果恰好等于它的因子之和,这个数就称为 "完数 "。示例6=1+2+3编程 找出1000以内的所有完数。   

public class lianxi09 {

public static void main(String[] args) {

 Systemoutprintln("1到1000的完数有: ");

 for(int i=1; i<1000; i++) {

  int t = 0;

  for(int j=1; j<= i/2; j++) {

   if(i % j == 0) {

    t = t + j;

   }

  }

  if(t == i) {

   Systemoutprint(i + " ");

  }

 }

}

}

。程序10。   

题目:1球从100米高度自由落下,每次落地后反跳回原高度的1;再落下,求它在 第10次落地时,共经过多少米?第10次反弹多高? 

public class lianxi10 {

public static void main(String[] args) {

  double h = 100,s = 0;

  for(int i=1; i<=10; i++) {

  s = s + 2*h;

  h = h / 2;

 }

  s=s-100;

 Systemoutprintln("经过路程:" + s);

 Systemoutprintln("最后高度:" + h);

}

}  

。程序11。   

题目:有1、2、3、4四个数字,能组成多少个互不相同且1个数字中无重复数字的三位数?并将他们都输入。   

public class lianxi11 {

public static void main(String[] args) {

 int count = 0;

 for(int x=1; x<5; x++) {

  for(int y=1; y<5; y++) {

   for(int z=1; z<5; z++) {

    if(x != y && y != z && x != z) {

     count ++;

     Systemoutprintln(x*100 + y*10 + z );

    }

   }

  }

 }

 Systemoutprintln("共有" + count + "个三位数");

}

。程序12。   

题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成75%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成15%,高于100万元时,超过100万元的部分按1%提成,从键盘输入当月利润,求应发放奖金总数?   

import javautil*;

public class lianxi12 {

public static void main(String[] args) {

 double x = 0,y = 0;

 Systemoutprint("输入当月利润(万):");

 Scanner s = new Scanner(Systemin);

 x = snextInt();

 if(x > 0 && x <= 10) {

 y = x * 01;

 } else if(x > 10 && x <= 20) {

  y = 10 * 01 + (x - 10) * 0075;

 } else if(x > 20 && x <= 40) {

  y = 10 * 01 + 10 * 0075 + (x - 20) * 005;

 } else if(x > 40 && x <= 60) {

  y = 10 * 01 + 10 * 0075 + 20 * 005 + (x - 40) * 003;

 } else if(x > 60 && x <= 100) {

  y = 20 * 0175 + 20 * 005 + 20 * 003 + (x - 60) * 0015; 

 } else if(x > 100) {

  y = 20 * 0175 + 40 * 008 + 40 * 0015 + (x - 100) * 001;

 }

 Systemoutprintln("应该提取的奖金是 " + y + "万");

}

}

。程序13。   

题目:1个整数,它加上100后是1个完全平方数,再加上168又是1个完全平方数,请问该数是多少?   

public class lianxi13 {

public static void main(String[] args) {

 for(int x =1; x<100000; x++) {

  if(Mathsqrt(x+100) % 1 == 0) {

   if(Mathsqrt(x+168) % 1 == 0) {

    Systemoutprintln(x + "加100是1个完全平方数,再加168又是1个完全平方数");

   }

  }

 }

}

}

 

/*按题意循环应该从-100开始(整数包括正整数、负整数、零),这样会多1个满足条件的数-99

但是我看到大部分人解这道题目时都将题中的整数理解成正整数,我也就随大流了。*/

。程序14。  

题目:输入某年某月某日,判断这1天是这1年的第几天?   

import javautil*;

public class lianxi14 {

public static void main(String[] args) {

 int year, month, day;

 int days = 0;

 int d = 0;

 int e;

 input fymd = new input();

 do {

 e = 0;

 Systemoutprint("输入年:");

 year =fymdinput();

 Systemoutprint("输入月:");

 month = fymdinput();

 Systemoutprint("输入天:");

 day = fymdinput();

 if (year < 0 || month < 0 || month > 12 || day < 0 || day > 31) {

 Systemoutprintln("输入错误,请重新输入!");

 e=1 ; 

 }

 }while( e==1);

 

  for (int i=1; i <month; i++) {

  switch (i) {

  case 1:

  case 3:

  case 5:

  case 7:

  case 8:

  case 10:

  case 12:

   days = 31;

  break;

  case 4:

  case 6:

  case 9:

  case 11:

   days = 30;

  break;

  case 2:

   if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) {

    days = 29;

   } else {

    days = 28;

   }

   break;

  }

  d += days;

  }

 Systemoutprintln(year + "-" + month + "-" + day + "是这年的第" + (d+day) + "天。");

}

}

class input{

public int input() {

 int value = 0;

 Scanner s = new Scanner(Systemin);

 value = snextInt();

 return value;

}

}

。程序15。   

题目:输入三个整数x,y,z,请将这三个数由小到大输出。   

import javautil*;

public class lianxi15 {

public static void main(String[] args) {

 input fnc = new input();

 int x=0, y=0, z=0;

 Systemoutprint("输入第1个数字:");

  x = fncinput();

 Systemoutprint("输入第2个数字:");

  y = fncinput();

 Systemoutprint("输入第三个数字:");

  z = fncinput();   

    if(x > y) {

  int t = x;

  x = y;

  y = t;

 }

    if(x > z) {

  int t = x;

  x = z;

  z = t;

 }

    if(y > z) {

  int t = y;

  y = z;

  z = t;

 }

    Systemoutprintln( "三个数字由小到大排列为: "+x + " " + y + " " + z);

}

}

class input{

public int input() {

 int value = 0;

 Scanner s = new Scanner(Systemin);

 value = snextInt();

 return value;

}

。程序16。

题目:输出9*9口诀。 

public class lianxi16 {

public static void main(String[] args) {

 for(int i=1; i<10; i++) {

  for(int j=1; j<=i; j++) {

   Systemoutprint(j + "*" + i + "=" + j*i + "    " );

     if(j*i<10){Systemoutprint(" ");}

}

  Systemoutprintln();

 }

}

。程序17。   

题目:猴子吃桃问题:猴子第1天摘下若干个桃子,当即吃了1半,还不瘾,又多吃了1 第2天早上又将剩下的桃子吃掉1半,又多吃了1个。以后每天早上都吃了前1天剩下 的1半零1个。到第10天早上想再吃时,见只剩下1个桃子了。求第1天共摘了多少。   

public class lianxi17 {

public static void main(String[] args) {

 int x = 1;

 for(int i=2; i<=10; i++) {

  x = (x+1)*2;

 }

 Systemoutprintln("猴子第1天摘了 " + x + " 个桃子");

}

}

。程序18。   

题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。   

public class lianxi18 {

static char[] m = { 'a', 'b', 'c' };

static char[] n = { 'x', 'y', 'z' };

public static void main(String[] args) {

   for (int i = 0; i < mlength; i++) {

    for (int j = 0; j < nlength; j++) {

 if (m[i] == 'a' && n[j] == 'x') {

  continue;

} else if (m[i] == 'a' && n[j] == 'y') {

  continue;

 } else if ((m[i] == 'c' && n[j] == 'x')

   || (m[i] == 'c' && n[j] == 'z')) {

  continue;

 } else if ((m[i] == 'b' && n[j] == 'z')

   || (m[i] == 'b' && n[j] == 'y')) {

  continue;

 } else

  Systemoutprintln(m[i] + " vs " + n[j]);

    }

   }

}

}

。程序19。   

题目:打印出如下图案(菱形)   

 *   

   ***   

 *****   

*******   

 *****   

   ***   

    *   

public class lianxi19 {

public static void main(String[] args) {

    int H = 7, W = 7;//高和宽必须是相等的奇数

    for(int i=0; i<(H+1) / 2; i++) {

 for(int j=0; j<W/2-i; j++) {

  Systemoutprint(" ");

 }

 for(int k=1; k<(i+1)*2; k++) {

  Systemoutprint('*');

 }

 Systemoutprintln();

    }

    for(int i=1; i<=H/2; i++) {

 for(int j=1; j<=i; j++) {

  Systemoutprint(" ");

 }

 for(int k=1; k<=W-2*i; k++) {

  Systemoutprint('*');

 }

 Systemoutprintln();

    }

}

}

。程序20。   

题目:有1分数序列:2/1,3/2,5/3,8/5,13/8,21/13、、、求出这个数列的前20项之和。 

public class lianxi20 {

public static void main(String[] args) {

    int x = 2, y = 1, t;

    double sum = 0;

    for(int i=1; i<=20; i++) {

 sum = sum + (double)x / y;

 t = y;

 y = x;

 x = y + t;

 }

Systemoutprintln("前20项相加之和是: " + sum);

}

}

。程序21。   

题目:求1+2!+3!+、、、+20!的和   

public class lianxi21 {

public static void main(String[] args) {

    long sum = 0; 

    long fac = 1;

    for(int i=1; i<=20; i++) {

 fac = fac * i;

 sum += fac;

    }

    Systemoutprintln(sum);

}

}

。程序22。   

题目:利用递归方法求5!。   

public class lianxi22 {

public static void main(String[] args) {

   int n = 5;

    rec fr = new rec();

    Systemoutprintln(n+"! = "+frrec(n));

}

}

class rec{

public long rec(int n) {

    long value = 0 ;

    if(n ==1 ) {

 value = 1;

    } else   {

 value = n * rec(n-1);

    }

    return value;

}

。程序23。   

题目:有5个人坐在1起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第1个人大两岁。最后问第1个人,他说是10岁。请问第五个人多大?   

public class lianxi23 {

public static void main(String[] args) {

    int age = 10;

 for(int i=2; i<=5; i++) {

 age =age+2;

    }

    Systemoutprintln(age);

}

。程序24。   

题目:给1个不多于5位的正整数,要求:1、求它是几位数,二、逆序打印出各位数字。   

//使用了长整型最多输入18位

import java、util、*;

public class lianxi24 {

public static void main(String[] args) {

   Scanner s = new Scanner(System、in);

   System、out、print("请输入1个正整数:");

   long a = s、nextLong();

   String ss = Long、toString(a);

    char[] ch = ss、toCharArray();

    int j=ch、length;

    System、out、println(a + "是1个"+ j +"位数。");

    System、out、print("按逆序输出是:");

    for(int i=j-1; i>=0; i--) {

    System、out、print(ch[i]);

   }

   }

   }

。程序25。   

题目:1个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。   

import java、util、*;

public class lianxi25 {

public static void main(String[] args) {

    Scanner s = new Scanner(System、in);

    int a;

    do{

 System、out、print("请输入1个5位正整数:");

  a = s、nextInt();

  }while(a<10000||a>99999);

 String ss =String、valueOf(a);

 char[] ch = ss、toCharArray();

 if(ch[0]==ch[4]&&ch[1]==ch[3]){

 System、out、println("这是1个回文数");}

 else {System、out、println("这不是1个回文数");}

    }

    }

//这个更好,不限位数

import java、util、*;

public class lianxi25a {

public static void main(String[] args) {

   Scanner s = new Scanner(System、in);

   boolean is =true;

   System、out、print("请输入1个正整数:");

   long a = s、nextLong();

   String ss = Long、toString(a);

   char[] ch = ss、toCharArray();

   int j=ch、length;

   for(int i=0; i<j/2; i++) {

   if(ch[i]!=ch[j-i-1]){is=false;}

   }

   if(is==true){System、out、println("这是1个回文数");}

 else {System、out、println("这不是1个回文数");}

    }

   }

。程序26。   

题目:请输入星期几的第1个字母来判断1下是星期几,如果第1个字母1样,则继续   判断第2个字母。   

import java、util、*;

public class lianxi26 {

public static void main(String[] args) {

    getChar tw = new getChar();

    System、out、println("请输入星期的第1个大写字母:");

    char ch = tw、getChar();

    switch(ch) {

 case 'M': 

  System、out、println("Monday");

  break;

 case 'W': 

  System、out、println("Wednesday");

  break;

 case 'F':

  System、out、println("Friday");

  break;

 case 'T': {

  System、out、println("请输入星期的第2个字母:");

  char ch2 = tw、getChar();

  if(ch2 == 'U') {System、out、println("Tuesday"); }

  else if(ch2 == 'H') {System、out、println("Thursday"); }

  else {System、out、println("无此写法!");

   }

 }; 

  break;

 case 'S': {

   System、out、println("请输入星期的第2个字母:");

  char ch2 = tw、getChar();

  if(ch2 == 'U') {System、out、println("Sunday"); }

   else if(ch2 == 'A') {System、out、println("Saturday"); }

   else {System、out、println("无此写法!");

   }

 };

  break;

default:System、out、println("无此写法!");

}

   }

}

 

class getChar{

public char getChar() {

    Scanner s = new Scanner(System、in);

    String str = s、nextLine();

    char ch = str、charAt(0);

    if(ch<'A' || ch>'Z') {

 System、out、println("输入错误,请重新输入");

 ch=getChar();

    }

    return ch;

}

}  

。程序27。   

题目:求100之内的素数   

//使用除sqrt(n)的方法求出的素数不包括2和3

public class lianxi27 {

public static void main(String[] args) {

    boolean b =false;

    System、out、print(2 + " ");

    System、out、print(3 + " ");

    for(int i=3; i<100; i+=2) {

 for(int j=2; j<=Math、sqrt(i); j++) {

  if(i % j == 0) {b = false;

      break;

   } else{b = true;}

 }

   if(b == true) {System、out、print(i + " ");}

    }

   }

}

//该程序使用除1位素数得2位方法,运行效率高通用性差。

public class lianxi27a {

public static void main(String[] args) {

    int[] a = new int[]{2, 3, 5, 7};

   for(int j=0; j<4; j++)System、out、print(a[j] + " ");

    boolean b =false;

    for(int i=11; i<100; i+=2) {

 for(int j=0; j<4; j++) {

  if(i % a[j] == 0) {b = false;

      break;

   } else{b = true;}

 }

   if(b == true) {System、out、print(i + " ");}

    }

   }

}

。程序28。   

题目:对10个数进行排序   

import java、util、*;

public class lianxi28 {

public static void main(String[] args) {

Scanner s = new Scanner(System、in);

   int[] a = new int[10];

   System、out、println("请输入10个整数:");

   for(int i=0; i<10; i++) {

    a[i] = s、nextInt();

   }

 

   for(int i=0; i<10; i++) {

    for(int j=i+1; j<10; j++) {

if(a[i] > a[j]) {

 int t = a[i];

 a[i] = a[j];

 a[j] = t;

}

    }

   }

   for(int i=0; i<10; i++) {

    System、out、print(a[i] + " ");

   }

}

}

。程序29。   

题目:求1个3*3矩阵对角线元素之和 

    

import java、util、*;

public class lianxi29 {

public static void main(String[] args) {

   Scanner s = new Scanner(System、in);

   int[][] a = new int[3][3];

System、out、println("请输入9个整数:");

   for(int i=0; i<3; i++) {

    for(int j=0; j<3; j++) {

 a[i][j] = s、nextInt();

    }

   }

   System、out、println("输入的3 * 3 矩阵是:");

   for(int i=0; i<3; i++) {

    for(int j=0; j<3; j++) {

 System、out、print(a[i][j] + " ");

    }

    System、out、println();

   }

   int sum = 0;

   for(int i=0; i<3; i++) {

    for(int j=0; j<3; j++) {

 if(i == j) {

  sum += a[i][j];

 }

    }

   }

   System、out、println("对角线之和是:" + sum);

}

}

 

。程序30。   

题目:有1个已经排好序的数组。现输入1个数,要求按原来的规律将它插入数组中。    

//此程序不好,没有使用折半查找插入

import javautil*;

public class lianxi30 {

public static void main(String[] args) {

   int[] a = new int[]{1, 2, 6, 14, 25, 36, 37,55};

   int[] b = new int[alength+1];

  int t1=0, t2 = 0;           

   int i =0;

   Scanner s= new Scanner(Systemin);

   Systemoutprint("请输入1个整数:");

   int num = snextInt();

   if(num >= a[alength-1]) {

    b[blength-1] = num;

    for(i=0; i<alength; i++) {

 b[i] = a[i];

    }

   } else {

    for(i=0; i<alength; i++) {

if(num >= a[i]) {

  b[i] = a[i];

 } else { 

  b[i] = num;

  break;

 }

    }

    for(int j=i+1; j<blength; j++) {

 b[j] = a[j-1];

    }

   }

   for (i = 0; i < blength; i++) {

    Systemoutprint(b[i] + " ");

   }

}           

}

。程序31。

题目:将1个数组逆序输出。   

import java、util、*;

public class lianxi31 {

public static void main(String[] args) {

   Scanner s = new Scanner(System、in);

   int a[] = new int[20];

System、out、println("请输入多个正整数(输入-1表示结束):");

   int i=0,j;

   do{

  a[i]=s、nextInt();

  i++;

   }while (a[i-1]!=-1);

 

   Systemoutprintln("你输入的数组为:");

   for( j=0; j<i-1; j++) {

    Systemoutprint(a[j]+"   ");

}

   Systemoutprintln("\n数组逆序输出为:");

   for( j=i-2; j>=0; j=j-1) {

    Systemoutprint(a[j]+"   ");

}

    }

   }

。程序32。   

题目:取1个整数a从右端开始的4~7位。   

import javautil*;

public class lianxi32 {

public static void main(String[] args) {

    Scanner s = new Scanner(Systemin);

    Systemoutprint("请输入17位以上的正整数:");

    long a = snextLong();

    String ss = LongtoString(a);

    char[] ch = sstoCharArray();

    int j=chlength;

    if (j<7){Systemoutprintln("输入错误!");}

    else {

 Systemoutprintln("截取从右端开始的4~7位是:"+ch[j-7]+ch[j-6]+ch[j-5]+ch[j-4]);

 }

    }

    } 

。程序33。  

题目:打印出杨辉三角形(要求打印出10行如下图)  

    1   

  1    1   

    1    2    1   

  1    3    3    1   

    1    4    6    4    1   

1    5    10    10    5    1   

…………

public class lianxi33 {

public static void main(String[] args) {

    int[][] a = new int[10][10];

   for(int i=0; i<10; i++) {

    a[i][i] = 1;

    a[i][0] = 1;

   }

   for(int i=2; i<10; i++) {

    for(int j=1; j<i; j++) {

 a[i][j] = a[i-1][j-1] + a[i-1][j];

    }

   }

 for(int i=0; i<10; i++) {

    for(int k=0; k<2*(10-i) 1; k++) {

 Systemoutprint(" ");

    }

    for(int j=0; j<=i; j++) {

 Systemoutprint(a[i][j] + "   ");

    }

    Systemoutprintln();

   }

}

}

。程序34。   

题目:输入3个数a,b,c,按大小顺序输出。   

import javautilScanner;

public class lianxi34 {

public static void main(String[] args) {

    Scanner s = new Scanner(Systemin);

    Systemoutprintln("请输入3个整数:");

    int a = snextInt();

    int b = snextInt();

    int c = snextInt();

  if(a < b) {

 int t = a;

 a = b;

 b = t;

    }

  if(a < c) {

 int t = a;

 a = c;

 c = t;

    }

 if(b < c) {

 int t = b;

 b = c;

 c = t;

    }

    Systemoutprintln("从大到小的顺序输出:");

    Systemoutprintln(a + " " + b + " " + c);

}

。程序35。   

题目:输入数组,最大的与第1个元素交换,最小的与最后1个元素交换,输出数组。   

import javautil*;

public class lianxi35 {

public static void main(String[] args) {

int N = 8;

int[] a = new int[N];// 创建1个八个元素的数组

Scanner s = new Scanner(Systemin);

int idx1 = 0, idx2 = 0;

Systemoutprintln("请输入8个整数:");

for (int i = 0; i < N; i++) {

a[i] = snextInt();

}

// 获得输入的八个数字

Systemoutprintln("你输入的数组为:");

for (int i = 0; i < N; i++) {

Systemoutprint(a[i] + " ");

}

// 输出输入的数组

int max = a[0], min = a[0];

for (int i = 0; i < N; i++) {

if (a[i] > max) {

max = a[i];

idx1 = i;

}

// 找出最大的数和其下标

if (a[i] < min) {

min = a[i];

idx2 = i;

}// 找出最大的数和其下标

}

if (idx1 != 0) {

int temp = a[0];

a[0] = a[idx1];

a[idx1] = temp;

}// 最大的数和第1个数交换位置

if (idx2 != N - 1) {

int temp = a[N - 1];

a[N - 1] = a[idx2];

a[idx2] = temp;

}// 最小的数和最后1个数交换位置

Systemoutprintln("\n交换后的数组为:");

for (int i = 0; i < N; i++) {

Systemoutprint(a[i] + " ");

}

}

}

。程序36。   

题目:有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数   

import java、util、Scanner;

public class lianxi36 {

public static void main(String[] args) {

   int N =10;

   int[] a = new int[N];

   Scanner s = new Scanner(System、in);

   System、out、println("请输入10个整数:");

   for(int i=0; i<N; i++) {

    a[i] = s、nextInt();

   }

   System、out、print("你输入的数组为:");

   for(int i=0; i<N; i++) {

 System、out、print(a[i] + " ");

   }

   System、out、print("\n请输入向后移动的位数:");

   int m = s、nextInt();

   int[] b = new int[m];

   for(int i=0; i<m; i++) {

    b[i] = a[N-m+i];

   }

   for(int i=N-1; i>=m; i--) {

   a[i] = a[i-m];

   }

   for(int i=0; i<m; i++) {

    a[i] = b[i];

   }

System、out、print("位移后的数组是:");

   for(int i=0; i<N; i++) {

    System、out、print(a[i] + " ");

   }

}

}

。程序37。   

题目:有n个人围成1圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。   

import java、util、Scanner;

public class lianxi37 {

public static void main(String[] args) {

   Scanner s = new Scanner(System、in);

   System、out、print("请输入排成1圈的人数:");

   int n = s、nextInt();

   boolean[] arr = new boolean[n];

   for(int i=0; i<arr、length; i++) {

    arr[i] = true;

   }//数组赋值都是true

   int leftCount = n;

   int countNum = 0;

   int index = 0;

   while(leftCount > 1) {

    if(arr[index] == true) {

 countNum ++; 

 if(countNum == 3) {

  countNum =0;

  arr[index] = false;

  leftCount --;

 }

    }

 index ++;

if(index == n) {

index = 0;

    }

   }

    for(int i=0; i<n; i++) {

    if(arr[i] == true) {

 System、out、println("原排在第"+(i+1)+"位的人留下了。");

    }

   }

}

}

。程序38。   

题目:写1个函数,求1个string的长度,在main函数中输入string,并输出其长度。   

/*………………

*……题目意思似乎不能用length()函数 */

import java、util、*;

public class lianxi38 {

public static void main(String[] args) {

    Scanner s = new Scanner(System、in);

    System、out、println("请输入1个string:");

    String str = s、nextLine();

 System、out、println("string的长度是:"+str、length());

    }

    } 

。程序39。   

题目:编写1个函数,输入n为偶数时,调用函数求1/2+1/4+、、、+1/n,当输入n为奇数时,调用函数1/1+1/3+、、、+1/n(利用指针函数)   

//没有利用指针函数

import java、util、*;

public class lianxi39 {

public static void main(String[] args) {

    Scanner s = new Scanner(System、in);

    System、out、print("请输入1个正整数 n= ");

    int n = s、nextInt();

    System、out、println("相应数列的和为:" + sum(n));

   }

public static double sum(int n) {

    double res = 0;

    if(n % 2 == 0) {

 for(int i=2; i<=n; i+=2) {

  res += (double)1 / i;

 } 

    } else {

 for(int i=1; i<=n; i+=2) {

  res += (double)1 / i ;

 }

    }

    return res;

}

。程序40。   

题目:string排序。   

public class lianxi40 {

public static void main(String[] args) {

   int N=5;

   String temp = null;

   String[] s = new String[N];

   s[0] = "matter";

   s[1] = "state";

   s[2] = "solid";

   s[3] = "liquid";

   s[4] = "gas";

   for(int i=0; i<N; i++) {

    for(int j=i+1; j<N; j++) {

 if(compare(s[i], s[j]) == false) {

  temp = s[i];

  s[i] = s[j];

  s[j] = temp;

 }

    }

   }

    for(int i=0; i<N; i++) {

    System、out、println(s[i]);

   }

}

static boolean compare(String s1, String s2) {

   boolean result = true;

   for(int i=0; i<s1、length() && i<s2、length(); i++) {

    if(s1、charAt(i) > s2、charAt(i)) {

 result = false;

 break;

    } else if(s1、charAt(i) <s2、charAt(i)) {

 result = true;

 break;

    } else {

 if(s1、length() < s2、length()) {

  result = true;

 } else {

  result = false;

 }

    }

   }

   return result;

}

}

。程序41。   

题目:海滩上有1堆桃子,五只猴子来分。第1只猴子将这堆桃子凭据分为五份,多了1个,这只猴子将多的1个扔入海中,拿走了1份。第2只猴子将剩下的桃子又平均分成五份,又多了1个,它同样将多的1个扔入海中,拿走了1份,第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子?   

public class lianxi41 { 

public static void main (String[] args) { 

int i,m,j=0,k,count; 

for(i=4;i<10000;i+=4) 

   { count=0; 

 m=i; 

 for(k=0;k<5;k++) 

    { 

     j=i/4*5+1; 

     i=j; 

     if(j%4==0) 

    count++; 

    else break; 

   } 

    i=m; 

if(count==4) 

{System、out、println("原有桃子 "+j+" 个"); 

break;} 

。程序42。   

题目:809*??=800*??+9*??+1    其中??代表的两位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果。   

//题目错了!809x=800x+9x+1 这样的方程无解。去掉那个1就有解了。

public class lianxi42 { 

public static void main (String[] args) { 

int a=809,b,i;

for(i=10;i<13;i++)

{b=i*a ;

if(8*i<100&&9*i>=100)

System、out、println ("809*"+i+"="+"800*"+i+"+"+"9*"+i+"="+b);}

}

。程序43。   

题目:求0—7所能组成的奇数个数。   

//组成1位数是4个。

//组成2位数是7*4个。

//组成3位数是7*8*4个。

//组成4位数是7*8*8*4个。

//、、、、、、

public class lianxi43 { 

public static void main (String[] args) { 

int sum=4;

int j;

System、out、println("组成1位数是 "+sum+" 个");

sum=sum*7;

System、out、println("组成2位数是 "+sum+" 个");

for(j=3;j<=9;j++){

sum=sum*8; 

System、out、println("组成"+j+"位数是 "+sum+" 个");

}

}

。程序44。   

题目:1个偶数总能表示为两个素数之和。   

//由于用除sqrt(n)的方法求出的素数不包括2和3,

//因此在判断是否是素数程序中人为添加了1个3。

import java、util、*;

public class lianxi44 {

public static void main(String[] args) {

Scanner s = new Scanner(System、in);

int n,i;

do{

 System、out、print("请输入1个大于等于6的偶数:");

 n = s、nextInt();

    } while(n<6||n%2!=0);   //判断输入是否是>=6偶数,不是,重新输入

fun fc = new fun();

    for(i=2;i<=n/2;i++){

    if((fc、fun(i))==1&&(fc、fun(n-i)==1)) 

    {int j=n-i;

 System、out、println(n+" = "+i+" + "+j);

 } //输出所有可能的素数对

   }

}

}

class fun{

public int fun (int a)    //判断是否是素数的函数

{

int i,flag=0;

if(a==3){flag=1;return(flag);}

for(i=2;i<=Math、sqrt(a);i++){

   if(a%i==0) {flag=0;break;}

  else flag=1;}

return (flag) ;//不是素数,返回0,是素数,返回1

}

}

//解法二

import java、util、*;

public class lianxi44 {

public static void main(String[] args) {

Scanner s = new Scanner(System、in);

int n;

do{

 System、out、print("请输入1个大于等于6的偶数:");

 n = s、nextInt();

    } while(n<6||n%2!=0);   //判断输入是否是>=6偶数,不是,重新输入

    for(int i=3;i<=n/2;i+=2){

    if(fun(i)&&fun(n-i)) {

  System、out、println(n+" = "+i+" + "+(n-i));

  } //输出所有可能的素数对

   }

}

static boolean fun (int a){    //判断是否是素数的函数

boolean flag=false;

if(a==3){flag=true;return(flag);}

for(int i=2;i<=Math、sqrt(a);i++){

   if(a%i==0) {flag=false;break;}

  else flag=true;}

return (flag) ;

}

}

。程序45。   

题目:判断1个素数能被几个9整除   

//题目错了吧?能被9整除的就不是素数了!所以改成整数了。

import java、util、*;

public class lianxi45 { 

public static void main (String[] args) { 

   Scanner s = new Scanner(System、in);

   System、out、print("请输入1个整数:");

    int num = s、nextInt();

    int   tmp = num;

    int count = 0; 

   for(int i = 0 ; tmp%9 == 0 ;){

   tmp = tmp/9;

    count ++;

  }

 System、out、println(num+" 能够被 "+count+" 个9整除。");

 }

。程序46。   

题目:两个string连接程序   

import java、util、*;

public class lianxi46 {

public static void main(String[] args) {

    Scanner s = new Scanner(System、in);

    System、out、print("请输入1个string:");

    String str1 = s、nextLine();

    System、out、print("请再输入1个string:");

    String str2 = s、nextLine();

    String str = str1+str2;

    System、out、println("连接后的string是:"+str);

    }

    } 

。程序47。   

题目:读取7个数(1—50)的整数值,每读取1个值,程序打印出该值个数的*。   

import java、util、*;

public class lianxi47 {

public static void main(String[] args) {

Scanner s = new Scanner(System、in);

int n=1,num;

while(n<=7){

     do{

  System、out、print("请输入1个1--50之间的整数:");

     num= s、nextInt();

   }while(num<1||num>50);

  for(int i=1;i<=num;i++)

  {System、out、print("*");

  }

System、out、println();

n ++;

}

}

。程序48。   

题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密要求如下:每位数字都加上5,然后用和除以10的余数代替该数字,再将第1位和第四位交换,第2位和第三位交换。   

import java、util、*;

public class lianxi48   { 

public static void main(String args[]) { 

Scanner s = new Scanner(System、in);

int num=0,temp;

do{

   System、out、print("请输入1个4位正整数:");

  num = s、nextInt();

 }while (num<1000||num>9999); 

int a[]=new int[4]; 

a[0] = num/1000; //取千位的数字 

a[1] = (num/100)%10; //取百位的数字 

a[2] = (num/10)%10; //取十位的数字 

a[3] = num%10; //取个位的数字 

for(int j=0;j<4;j++) 

a[j]+=5; 

a[j]%=10; 

for(int j=0;j<=1;j++) 

    { 

    temp = a[j]; 

    a[j] = a[3-j]; 

    a[3-j] =temp; 

    } 

System、out、print("加密后的数字为:"); 

for(int j=0;j<4;j++) 

System、out、print(a[j]); 

。程序49。   

题目:计算string中子串出现的次数   

import java、util、*;

public class lianxi49 { 

public static void main(String args[]){

Scanner s = new Scanner(System、in);

    System、out、print("请输入string:");

    String str1 = s、nextLine();

    System、out、print("请输入子串:");

    String str2 = s、nextLine();

int count=0; 

if(str1、equals("")||str2、equals("")) 

   { 

   System、out、println("你没有输入string或子串,无法比较!"); 

   System、exit(0); 

   } 

else 

   { 

    for(int i=0;i<=str1、length() str2、length();i++) 

 { 

 if(str2、equals(str1、substring(i, str2、length()+i))) 

  //这种比法有问题,会将"aaa"看成有2个"aa"子串。 

   count++; 

   } 

System、out、println("子串在string中出现: "+count+" 次"); 

}

。程序50。   

题目:有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩),计算出平均成绩,将原有的数据和计算出的平均分数存放在磁盘文件 "stud "中。

import java、io、*; 

import java、util、*;

public class lianxi50 { 

public static void main(String[] args){ 

   Scanner ss = new Scanner(System、in);

   String [][] a = new String[5][6];

   for(int i=1; i<6; i++) {

    System、out、print("请输入第"+i+"个学生的学号:");

    a[i-1][0] = ss、nextLine();

    System、out、print("请输入第"+i+"个学生的姓名:");

    a[i-1][1] = ss、nextLine();

    for(int j=1; j<4; j++) {

   System、out、print("请输入该学生的第"+j+"个成绩:");

   a[i-1][j+1] = ss、nextLine();

   }

System、out、println("\n");

   }

//以下计算平均分

float avg;

int sum;

for(int i=0; i<5; i++) {

sum=0;

   for(int j=2; j<5; j++) {

   sum=sum+ Integer、parseInt(a[i][j]);

  }

   avg= (float)sum/3;

   a[i][5]=String、valueOf(avg);

}

//以下写磁盘文件 

String s1; 

try { 

    File f = new File("C:\\stud"); 

    if(f、exists()){ 

  System、out、println("文件存在"); 

  }else{ 

     System、out、println("文件不存在,正在创建文件"); 

  f、createNewFile();//不存在则创建 

    } 

BufferedWriter output = new BufferedWriter(new FileWriter(f)); 

for(int i=0; i<5; i++) {

for(int j=0; j<6; j++) {

   s1=a[i][j]+"\r\n";

   output、write(s1);    

    }

}

output、close(); 

System、out、println("数据已写入c盘文件stud中!");

   } catch (Exception e) { 

 e、printStackTrace(); 

 } 

}

}

自己写的程序:

1、 判断1个数是否为素数

public class lianxi33 {

public static void main(String[] args) {

for (int i = 1; i <=10000; i++) {

int n = i;

if (isPrime(n)) {

Systemoutprintln(i + "是素数");

}

}

}

// 输入1个数判断其是否为素数

public static boolean isPrime(int n) {

if (n <= 1) {

return false;

}

if (n == 2) {

return true;

}

if (n % 2 == 0) {

return false;

}

for (int i = 3; i <= (int) (Mathfloor(Mathsqrt(n))) + 1; i = i + 2) {

if (n % i == 0) {

return false;

}

}

return true;

}

}

2、二分法查找

public class BinarySearch {

public static int binarySearch(int[] a, int x) {

// a[0]<=a[1]<=、、、<=a[n-1]中搜索x

// 找到x则返回x的所在位置,否则返回-1

int left = 0;

int right = alength - 1;

while (left <= right) {

int middle = (left + right) / 2;

if (x == a[middle])

return middle;

if (x > a[middle])

left = middle + 1;

else

right = middle - 1;

}

return -1;

}

public static void main(String[] args) {

int[] a = { 0, 1, 3, 6, 7, 10, 21, 34, 36, 40, 76 };

int x = 34;// 设定要查找的数

int position = binarySearch(a, x);

Systemoutprintln(x + "在数组中的位置是" + position);

}

}

2、 比较器 二分查找

   import javautilTreeSet;

import javautilIterator;

public class Student implements Comparable<Student> {

    private int id;

    private String name;

    private String dengji;

    public Student (int id, String name, String dengji) {

    thisid = id;

    thisname = name;

    thisdengji=dengji;

    }

    public void setId (int id) {

    thisid = id;

    }

    public void setName (String name) {

    thisname = name;

    }

    public void setDengji (String dengji) {

    thisdengji = dengji;

    }

    public int getId () {

    return id;

    }

    public String getName () {

    return name;

    }

    public String getdengji () {

    return dengji;

    }

    /* Student 类的string表达式,形如:

     * 2   张三 */

    public String toString () {

    return (id + "\t" + name+"\t" + dengji);

    }

    /* 实现 Comparable 接口中的 compareTo 方法,

     * 通常大于时返回1个正数,小于时返回1个负数,

     * 等于时返回零,具体情况可以自行决定。

     *********************************************************

     * 这里我根据 id 号的大小进行了比较。由于 TreeSet

     * 会根据 compareTo 的结果来排序,因此输出结果

     * 应该是按照 id 号从小到大排序的。

     * 如果要根据姓名进行排序,只需对这个方法进行相应的修改。*/

    public int compareTo (Student arg) {

    if (id > argid)

        return 1;

    else if (id == argid)

        return 0;

    else

        return -1;

    }

    /* 以下为主方法,输出结果是:

     * 3 John

     * 5 Tom

     * 7 Alice

     * 9 David

     * 可以看到不同于输入顺序,

     * TreeSet 已经将其排序了。*/

    public static void main (String args[]) {

    TreeSet<Student> tset = new TreeSet<Student>();

    tsetadd(new Student(5, "Tom" ,  "a"));

    tsetadd(new Student(3, "John",  "b" ));

    tsetadd(new Student(9, "David",  "c" ));

    tsetadd(new Student(7, "Alice" , "d"));

    Iterator<Student> itor = tsetiterator();

    while (itorhasNext()) {

        Systemoutprintln(itornext()toString());

    }

    }

}

**************************************************************************************************************************************************************

BinarySearch

import javautilComparator;

public class BinarySearch {

public static <T extends Comparable<T>> int binarySearch(T[] a, T x,

Comparator<T> comparator) {

if (a == null) {

throw new IllegalArgumentException("被查找数组为null");

else if (x == null) {

throw new IllegalArgumentException("被查询元素为null");

}

int left = 0;

int right = alength - 1;

while (left <= right) {

int middle = (left + right) / 2;

if (comparator != null) {

if (comparatorcompare(x, a[middle]) == 0)

return middle;

if (comparatorcompare(x, a[middle]) > 0)

left = middle + 1;

else

right = middle - 1;

}

  else { if(xcompareTo(a[middle])==0) 

  return middle;

  if(xcompareTo(a[middle])>0) 

  left = middle + 1; 

  else right = middle - 1; }

 

}

return -1;

}

public static void main(String[] args) {

Student[] a = new Student[4];

a[0] = (new Student(3, "Tom"));

a[1] = (new Student(5, "John"));

a[2] = (new Student(7, "David"));

a[3] = (new Student(9, "Alice"));

Student x = new Student(7, "John");// 设定要查找的数

int position = binarySearch(a, x, new StudentComparator());

Systemoutprintln(x + "在数组中的位置是" + position);

}

}

Student

import javautilTreeSet;

import javautilIterator;

public class Student implements Comparable<Student> {

   private int id;

   private String name;

   

   public Student (int id, String name) {

   thisid = id;

   thisname = name;

   

   }

   public void setId (int id) {

   thisid = id;

   }

   public void setName (String name) {

   thisname = name;

   }

   

   public int getId () {

   return id;

   }

   public String getName () {

   return name;

   }

   

   /* Student 类的string表达式,形如:

    * 2   张三 */

   public String toString () {

   return (id + "\t" + name+"\t" );

   }

   /* 实现 Comparable 接口中的 compareTo 方法,

    * 通常大于时返回1个正数,小于时返回1个负数,

    * 等于时返回零,具体情况可以自行决定。

    *********************************************************

    * 这里我根据 id 号的大小进行了比较。由于 TreeSet

    * 会根据 compareTo 的结果来排序,因此输出结果

    * 应该是按照 id 号从小到大排序的。

    * 如果要根据姓名进行排序,只需对这个方法进行相应的修改。*/

   public int compareTo (Student arg) {

   if (id > argid)

       return 1;

   else if (id == argid)

       return 0;

   else

       return -1;

   }

   /* 以下为主方法,输出结果是:

    * 3 John

    * 5 Tom

    * 7 Alice

    * 9 David

    * 可以看到不同于输入顺序,

    * TreeSet 已经将其排序了。*/

   public static void main (String args[]) {

   TreeSet<Student> tset = new TreeSet<Student>();

   tsetadd(new Student(5, "Tom" ));

   tsetadd(new Student(3, "John"));

   tsetadd(new Student(9, "David"));

   tsetadd(new Student(7, "Alice"));

   Iterator<Student> itor = tsetiterator();

   while (itorhasNext()) {

       Systemoutprintln(itornext()toString());

   }

   }

}

StudentComparator

import javautilComparator;

/**

 * Student 比较器

 */

public class StudentComparator implements Comparator<Student> 

{

@Override

public int compare(Student s1, Student s2) 

{

if(s1getId()>s2getId())

return 1;

else if(s1getId()==s2getId())

return 0;

else

return -1;

}

}

package test1; 

 

/**

 * Title: Hello Java World

 * Description: 简单的Java程序,只显示1个信息。

 * filename: HelloWorldjava

 */ 

 public class HelloWorld { 

  public static void main(String[] args) { 

    Systemoutprintln("Hello Java World!"); 

  } 

 } 

package test2; 

/**

 * Title: Java语言流程演示

 * Description: 演示Java中几种常用的流程控制操作

 * Filename: flowDomejava

 */ 

 public class flowDemo{ 

   public static void main(String[] arges){ 

 int iPara1,iPara2,iEnd; 

 if(argeslength!=3) 

 { 

   Systemoutprintln("USE :java flowDome parameter1 parameter2 circle"); 

   Systemoutprintln("parameter1 : 比较条件1,数字类型"); 

   Systemoutprintln("parameter2 : 比较条件2,数字类型"); 

   Systemoutprintln("circle :循环次数"); 

   Systemoutprintln("ego:java flowDome 1 2 5"); 

   return; 

 }else{ 

   iPara1 = IntegerparseInt(arges[0]); 

   iPara2 = IntegerparseInt(arges[1]); 

   iEnd = IntegerparseInt(arges[2]); 

 } 

 //if语句 

 if(iPara2>iPara1) 

 { 

  Systemoutprintln("if 条件满足!"); 

  Systemoutprintln("第2个数比第1个数大!"); 

 } 

 else 

 { 

  Systemoutprintln("if 条件不满足!"); 

  Systemoutprintln("第2个数比第1个数小!"); 

 } 

 //for循环操作 

 for(int i=0;i<iEnd;i++) 

 { 

   Systemoutprintln("这是for 第"+i+"次循环"); 

 } 

 //while循环操作 

 int i=0; 

 while(i<iEnd) 

 { 

  Systemoutprintln("这是while 第"+i+"次循环"); 

  i++; 

 } 

 //do-while循环操作 

 int j=0; 

 do 

 { 

  Systemoutprintln("这是do-while 第"+j+"次循环"); 

  j++; 

 }while(j<iEnd); 

   } 

 } 

 

package test3; 

 

/**

 * Title: 数组数据操作

 * Description: 演示1维数组和多维数组的初始化和基本操作

 * Filename: myArrayjava

 */ 

 public class  myArray{ 

   //初始化数组变量 

   char[] cNum = {'1','2','3','4','5','6','7','8','9','0'}; 

   char[] cStr = {'a','b','c','d','e','f','g','h', 

      'i','j','k','l','m','n','o','p', 

      'q','r','s','t','u','v','w','x','y','z'}; 

   int[] iMonth = {31,28,31,30,31,30,31,31,30,31,30,31}; 

   String[] sMail = {"@",""}; 

/**

 *<br>方法说明:校验电子邮件

 *<br>输入参数:String sPara 被校验的电子邮件字符

 *<br>返回类型:boolean 如果校验的格式符合电子邮件格式返回true;否则返回false

 */    

   public boolean isMail(String sPara){ 

    for(int i=0;i<sMaillength;i++){ 

  if(sParaindexOf(sMail[i])==-1) 

    return false;  

    } 

    return true; 

   } 

/**

 *<br>方法说明:判断是否是数字

 *<br>输入参数:String sPara。 需要判断的string

 *<br>返回类型:boolean。如果都是数字类型,返回true;否则返回false

 */    

   public boolean isNumber(String sPara){ 

 int iPLength = sParalength(); 

 for(int i=0;i<iPLength;i++){ 

  char cTemp = sParacharAt(i); 

  boolean bTemp = false; 

  for(int j=0;j<cNumlength;j++){ 

    if(cTemp==cNum[j]){ 

  bTemp = true; 

  break; 

    } 

  } 

  if(!bTemp) return false;  

 } 

    return true; 

   } 

/**

 *<br>方法说明:判断是否都是英文字符

 *<br>输入参数:String sPara。要检查的字符

 *<br>返回类型:boolean。如果都是字符返回true;反之为false

 */    

   public boolean isString(String sPara){ 

 int iPLength = sParalength(); 

 for(int i=0;i<iPLength;i++){ 

  char cTemp = sParacharAt(i); 

  boolean bTemp = false; 

  for(int j=0;j<cStrlength;j++){ 

    if(cTemp==cStr[j]){ 

  bTemp = true; 

  break; 

    } 

  } 

  if(!bTemp) return false;  

 } 

    return true; 

   } 

/**

 *<br>方法说明:判断是否是闰年

 *<br>输入参数:int iPara。要判断的年份

 *<br>返回类型:boolean。如果是闰年返回true,否则返回false

 */    

   public boolean chickDay(int iPara){ 

 return iPara%100==0&&iPara%4==0; 

   } 

/**

 *<br>方法说明:检查日期格式是否正确

 *<br>输入参数:String sPara。要检查的日期字符

 *<br>返回类型:int 0 日期格式正确,-1 月或这日不合要求, -2 年月日格式不正确 

 */ 

   public int chickData(String sPara){

    @SuppressWarnings("unused") 

    boolean bTemp = false; 

    //所输入日期长度不正确 

    if(sParalength()!=10) return -2; 

//获取年 

    String sYear = sParasubstring(0,4); 

//判断年是否为数字 

    if(!isNumber(sYear)) return -2;

//获取月份 

    String sMonth = sParasubstring(5,7); 2011 05 05

    //判断月份是否为数字 

    if(!isNumber(sMonth)) return -2; 

    //获取日 

    String sDay = sParasubstring(8,10); 

    //判断日是否为数字 

    if(!isNumber(sDay)) return -2; 

    //将年、月、日转换为数字 

    int iYear = IntegerparseInt(sYear); 

    int iMon = IntegerparseInt(sMonth); 

    int iDay = IntegerparseInt(sDay); 

    if(iMon>12) return -1; 

    //闰年二月处理 

    if(iMon==2&&chickDay(iYear)){ 

  if(iDay>29) return 2; 

    }else{ 

  if(iDay>iMonth[iMon-1]) return -1; 

    } 

    return 0; 

   } 

/**

 *<br>方法说明:主方法,测试用

 *<br>输入参数:

 *<br>返回类型:

 */  

   public static void main(String[] arges){ 

 myArray mA = new myArray(); 

 //校验邮件地址 

 boolean bMail = mAisMail("tom@163com"); 

 Systemoutprintln("1 bMail is "+bMail); 

 bMail = mAisMail("tom@163com"); 

 Systemoutprintln("2 bMail is "+bMail); 

 //演示是否是数字 

 boolean bIsNum = mAisNumber("1234"); 

 Systemoutprintln("1:bIsNum="+bIsNum); 

 bIsNum = mAisNumber("123r4"); 

 Systemoutprintln("2:bIsNum="+bIsNum); 

 //演示是否是英文字符 

 boolean bIsStr = mAisString("wer"); 

 Systemoutprintln("1:bIsStr="+bIsStr); 

 bIsStr = mAisString("wer3"); 

 Systemoutprintln("2:bIsStr="+bIsStr); 

 //演示检查日期 

 int iIsTime = mAchickData("2003-12-98"); 

 Systemoutprintln("1:iIsTime="+iIsTime); 

 iIsTime = mAchickData("2003-111-08"); 

 Systemoutprintln("2:iIsTime="+iIsTime); 

 iIsTime = mAchickData("2003-10-08"); 

 Systemoutprintln("3:iIsTime="+iIsTime); 

 iIsTime = mAchickData("2000-02-30"); 

 Systemoutprintln("4:iIsTime="+iIsTime); 

   } 

 } 

 

package test4; 

 

import javautil*; 

/**

 * Title: 矢量操作<

 * Description: 演示1个矢量(Vector)的基本操作

 * Filename: operateVectorjava

 */ 

public class operateVector  

/*

*<br>方法说明:生成14*4的二维Vector,供使用。

*<br>输入参数:

*<br>输出变量:Vector

*<br>其它说明:

*/ 

    public Vector<Object> buildVector(){ 

   Vector<Object> vTemps = new Vector<Object>(); 

   for(int i=0;i<4;i++){ 

  Vector<Object> vTemp = new Vector<Object>(); 

  for (int j=0;j<4;j++){ 

    vTempaddElement("Vector("+i+")("+j+")"); 

  } 

  vTempsaddElement(vTemp); 

   } 

   return vTemps; 

    } 

/*

*<br>方法说明:插入数据

*<br>输入参数:Vector vTemp 待插入的数据对象

*<br>输入参数:int iTemp 插入数据的位置

*<br>输入参数:Object oTemp 插入数据值

*<br>输出变量:Vector 结果

*<br>其它说明:如果插入位置超出实例实际的位置将返回null

*/ 

    public Vector<Object> insert(Vector<Object> vTemp,int iTemp,Object oTemp){ 

    if(iTemp>vTempsize()){ 

    print("数据超界!"); 

    return null; 

    }else{ 

     vTempinsertElementAt(oTemp,iTemp); 

    } 

    return vTemp; 

    } 

/*

*<br>方法说明:移除数据

*<br>输入参数:Vector vTemp 待删除矢量对象

*<br>输入参数:int iTemp 删除数据的位置

*<br>输出变量:Vector

*<br>其它说明:如果删除超界的数据,将返回null

*/ 

    public Vector<Object> delete(Vector<Object> vTemp,int iTemp){ 

    if(iTemp>vTempsize()){ 

    print("数据超界!"); 

    return null; 

    }else{ 

     vTempremoveElementAt(iTemp); 

    } 

    return vTemp; 

    } 

/*

*<br>方法说明:修改数据

*<br>输入参数:Vector vTemp 待修改矢量对象

*<br>输入参数:int iTemp 修改数据的位置

*<br>输入参数:Object oTemp 修改数据值

*<br>输出变量:Vector

*<br>其它说明:如果修改位置超界的数据,将返回null

*/ 

    public Vector<Object> updata(Vector<Object> vTemp,int iTemp,Object oTemp){ 

    if(iTemp>vTempsize()){ 

    print("数据超界!"); 

    return null; 

    }else{ 

     vTempsetElementAt(oTemp,iTemp); 

    } 

    return vTemp; 

    } 

/*

*<br>方法说明:输出信息

*<br>输入参数:String sTemp 输出信息名称

*<br>输入参数:Object oTemp 输出信息值

*<br>返回变量:无

*/ 

    public void print(String sTemp,Vector<Object> oTemp){ 

    Systemoutprintln(sTemp+"数据:"); 

    thisprint(oTemp); 

    } 

/**

 *<br>方法说明:打印输出(过载)

 *<br>输入参数:Object oPara 输出的对象

 *<br>返回类型:无

 */ 

    public void print(Object oPara){ 

    Systemoutprintln(oPara); 

    } 

/**

 *<br>方法说明:打印输出(过载)

 *<br>输入参数:Vector vPara 显示输出矢量对象

 *<br>返回类型:无

 */ 

    public void print(Vector<Object> vPara){ 

   for(int i=0;i<vParasize();i++){ 

    Systemoutprintln(vParaelementAt(i)); 

   } 

    } 

/**

 *<br>方法说明:主方法,程序入口

 *<br>输入参数:String[] args

 *<br>返回类型:无

 */ 

    public static void main(String[] args)  

    { 

    operateVector ov = new operateVector(); 

    Vector<Object> vTemp = ovbuildVector(); 

    ovprint("vTemp0",vTemp); 

    Vector<Object> vResult = ovinsert(vTemp,2,"添加的数据"); 

    ovprint("vResult",vResult); 

    Vector<Object> vResultup = ovupdata(vResult,2,"修改的数据"); 

    ovprint("vResultmp",vResultup); 

    Vector<Object> vResultnow = ovdelete(vResultup,2); 

    ovprint("vResultnow",vResultnow); 

    } 

 

package test5; 

 

import javautil*; 

/**

 * Title: 哈希表操作

 * Description: 这是1个权限认证的例子,使用了哈希表作为数据的存储

 * Filename: RoleRightjava

 */ 

 public class RoleRight 

 { 

 private static Hashtable<String, String> rightList = new Hashtable<String, String>(); 

/**

 *<br>方法说明:初始化数据

 *<br>输入参数:

 *<br>返回类型:

 */ 

 public void init() 

 { 

    String[] accRoleList = {"admin","satrap","manager","user","guest"}; 

    String[] rightCodeList = {"10001","10011","10021","20011","24011"}; 

    for(int i=0;i<accRoleListlength;i++) 

    { 

  rightListput(accRoleList[i],rightCodeList[i]); 

    } 

 } 

/**

 *<br>方法说明:获取角色权限代码

 *<br>输入参数:String accRole 角色名称

 *<br>返回类型:String 权限代码

 */ 

 public String getRight(String accRole) 

 { 

    if(rightListcontainsKey(accRole)) 

  return (String)rightListget(accRole); 

    else 

  return null; 

 } 

/**

 *<br>方法说明:添加角色和代码信息

 *<br>输入参数:String accRole 角色名称

 *<br>输入参数:String rightCode 角色权限代码 

 *<br>返回类型:void (无)

 */ 

 public void insert(String accRole,String rightCode) 

 { 

   rightListput(accRole,rightCode); 

 } 

/**

 *<br>方法说明:删除角色权限

 *<br>输入参数:String accRole 角色名称

 *<br>返回类型:void(无)

 */ 

 public void delete(String accRole) 

 { 

   if(rightListcontainsKey(accRole)) 

 rightListremove(accRole); 

 } 

/**

 *<br>方法说明:修改角色权限代码

 *<br>输入参数:String accRole 角色名称

 *<br>输入参数:String rightCode 角色权限代码 

 *<br>返回类型:void(无)

 */ 

 public void update(String accRole,String rightCode) 

 { 

   //thisdelete(accRole); 

   thisinsert(accRole,rightCode); 

 } 

/**

 *<br>方法说明:打印哈希表中角色和代码对应表

 *<br>输入参数:无

 *<br>返回类型:无

 */ 

 public void print() 

 { 

    Enumeration<String> RLKey = rightListkeys(); 

    while(RLKeyhasMoreElements()) 

    { 

    String accRole = RLKeynextElement()toString(); 

    print(accRole+"="+thisgetRight(accRole)); 

    } 

 } 

/**

 *<br>方法说明:打印信息(过载)

 *<br>输入参数:Object oPara 打印的信息内容

 *<br>返回类型:无

 */ 

 public void print(Object oPara) 

 { 

    Systemoutprintln(oPara); 

 } 

/**

 *<br>方法说明:主方法,

 *<br>输入参数:

 *<br>返回类型:

 */ 

 public static void main(String[] args) 

 { 

    RoleRight RR = new RoleRight(); 

    RRinit(); 

    RRprint(); 

    RRprint("___________________________"); 

    RRinsert("presider","10110"); 

    RRprint(); 

    RRprint("___________________________"); 

    RRupdate("presider","10100"); 

    RRprint(); 

    RRprint("___________________________"); 

    RRdelete("presider"); 

    RRprint(); 

 }  

 }//end:)~ 

 

package test6; 

 

/**

 * Title: 树参数

 * Description: 使用继承类,柳树就是树

 * Filename: osierjava

 */ 

class tree 

/**

 *<br>方法说明:树的树根

 */ 

  public void root() 

  { 

    String sSite = "土壤中"; 

    String sFunction = "吸收养份"; 

    print("位置:"+sSite); 

    print("功能:"+sFunction); 

  } 

/**

 *方法说明:树的树干

 */ 

  public void bolo() 

  { 

    String sSite = "地面"; 

    String sFunction = "传递养份"; 

    print("位置:"+sSite); 

    print("功能:"+sFunction); 

  } 

/**

 *方法说明:树的树枝

 */ 

  public void branch() 

  { 

    String sSite = "树干上"; 

    String sFunction = "传递养份"; 

    print("位置:"+sSite); 

    print("功能:"+sFunction); 

  } 

/**

 *方法说明:树的叶子

 */ 

  public void leaf() 

  { 

    String sSite = "树梢"; 

    String sFunction = "光合作用"; 

    String sColor = "绿色";

    print("位置:"+sSite); 

    print("功能:"+sFunction); 

    print("颜色:"+sColor); 

  } 

/**

 *方法说明:显示信息

 *输入参数:Object oPara 显示的信息

 */ 

  public void print(Object oPara) 

  { 

    Systemoutprintln(oPara); 

  } 

/**

 *方法说明:主方法:

 */ 

  public static void  main(String[] arges) 

  { 

    tree t = new tree(); 

    tprint("描述1棵树:"); 

    tprint("树根:"); 

    troot(); 

    tprint("树干:"); 

    tbolo(); 

    tprint("树枝:"); 

    tbranch(); 

    tprint("树叶:"); 

    tleaf(); 

  } 

/**

 * Title: 柳树参数

 * Description: 描述柳树的参数

 */ 

class osier extends tree 

 /**

 *方法说明:过载树的树叶

 */ 

  public void leaf() 

  { 

    superleaf(); 

    String sShape = "长形"; 

    superprint("形状:"+sShape); 

  } 

  /**

 *方法说明:扩展树的花

 */ 

  public void flower() 

  { 

    print("哈哈,柳树没有花!!"); 

  } 

/**

 *方法说明:主方法

 */ 

  public static void  main(String[] args) 

  { 

    osier o = new osier(); 

    oprint("柳树树根:"); 

    oroot(); 

    oprint("柳树树干:"); 

    obolo(); 

    oprint("柳树树枝:"); 

    obranch(); 

    oprint("柳树树叶:"); 

    oleaf(); 

    oprint("柳树花:"); 

    oflower(); 

  } 

 

package test7; 

 

/**

 *  Title:  接口和抽象函数 

 *  Description: 演示继承抽象函数和实现接口 

 *  Filename: newPlayjava

 */ 

  

//接口  

interface player 

 int flag = 1; 

 void play();//播放 

 void pause();//暂停 

 void stop();//停止 

}//end :) 

 

//抽象类 

abstract class playing 

 public void display(Object oPara) 

 { 

   Systemoutprintln(oPara);   

 } 

 abstract void winRun(); 

}//end :) 

 

//继承了playing抽象类和实现类player接口 

public class newPlay extends playing implements player 

  public void play() 

  { 

    display("newPlayplay()");//这里只是演示,去掉了代码。 

  } 

  public void pause() 

  { 

 display("newPlaypause()");//这里只是演示,去掉了代码。 

  } 

  public void stop() 

  { 

    display("newPlaystop()");//这里只是演示,去掉了代码。 

  } 

  void winRun() 

  { 

    display("newPlaywinRun()");//这里只是演示,去掉了代码。 

  } 

  public static void main(String[] args) 

  { 

    newPlay p = new newPlay(); 

    pplay(); 

    ppause(); 

    pstop(); 

    pwinRun(); 

  } 

}//end :) 

 

package test8com; 

 

/**

 * Title: 标识符

 * Description: 演示标识符对类的访问控制

 * Filename:

 */ 

public class classDemo1 { 

    // 公有方法 

    public void mechod1() { 

    Systemoutprintln("这是1个公有的方法!任何类都可以访问。"); 

    } 

 

    // 授保护的方法 

    protected void mechod2() { 

    Systemoutprintln("这是1个受到保护的方法!只有子类可以访问。"); 

    } 

 

    // 私有的方法 

    private void mechod3() { 

    Systemoutprintln("这是1个私有的方法!只有类本身才可以访问。"); 

    } 

 

    public static void main(String[] args) { 

    classDemo1 d = new classDemo1(); 

    dmechod1(); 

    dmechod2(); 

    dmechod3(); 

    } 

 

package test8com; 

/**

 * Title: 标识符

 * Description: 演示标识符对类的访问控制

 * Filename: 

 */ 

public class classPlay 

  public static void main(String[] args){ 

    classDemo1 d = new classDemo1(); 

    dmechod1(); 

    dmechod2(); 

    //dmechod3(); 

  } 

 

package test8net; 

 

import test8comclassDemo1; 

/**

 * Title: 标识符

 * Description: 演示标识符对类的访问控制

 * Filename: 

 */ 

public class classPlay 

  public static void main(String[] args){ 

    classDemo1 d = new classDemo1(); 

    dmechod1(); 

  //dmechod2(); 

  //dmechod3(); 

  } 

 

package test9; 

 

/**

 * Title: 捕获异常和实现自己的异常

 * Description: 通过继承Exception类来实现自己的异常类。并使用try-catch来捕获这个异常。

 * Filename:

 */ 

class MyException extends Exception { 

    private static final long serialVersionUID = 1L; 

 

    public MyException() { 

    } 

 

    public MyException(String msg) { 

    super(msg); 

    } 

 

    public MyException(String msg, int x) { 

    super(msg); 

    i = x; 

    } 

 

    public int val() { 

    return i; 

    } 

 

    private int i; 

 

public class DemoException { 

    /**

 *方法说明:使用MyException类中默认的构造器

 */ 

    public static void a() throws MyException { 

    Systemoutprintln("Throwing MyException from a()"); 

    throw new MyException(); 

    } 

 

    /**

 *方法说明:使用MyException类中带信息的构造器

 */ 

    public static void b() throws MyException { 

    Systemoutprintln("Throwing MyException from b()"); 

    throw new MyException("Originated in b()"); 

    } 

 

    /**

 *方法说明:使用了MyException中有编码的构造器

 */ 

    public static void c() throws MyException { 

    Systemoutprintln("Throwing MyException from c()"); 

    throw new MyException("Originated in c()", 47); 

    } 

 

    public static void main(String[] args) { 

    try { 

    a(); 

    } catch (MyException e) { 

    egetMessage(); 

    } 

    try { 

    b(); 

    } catch (MyException e) { 

    etoString(); 

    } 

    try { 

    c(); 

    } catch (MyException e) { 

    eprintStackTrace(); 

    Systemoutprintln("error code: " + eval()); 

    } 

    } 

} // end :) 

 

package test10; 

 

import javaxswing*; 

import javaawt*; 

 

/**

 * Title: 创建自己的窗体 

 * Description: 

 * Filename:mainFramejava

 */ 

public class mainFrame extends JFrame { 

 

    private static final long serialVersionUID = 1L; 

 

    /**

 *方法说明:构造器,通过传递参数来完成窗体的绘制。 

 *输入参数:String sTitle 窗体标题 

 *输入参数:int iWidth 窗体的宽度

 *输入参数:int iHeight 窗体的高度 返回类型:

 */ 

    public mainFrame(String sTitle, int iWidth, int iHeight) { 

    Dimension dim = ToolkitgetDefaultToolkit()getScreenSize();// 获取屏幕尺寸 

    ImageIcon ii = new ImageIcon("middlegif"); 

    setTitle(sTitle);// 设置窗体标题 

    setIconImage(iigetImage());// 设置窗体的图标 

    setDefaultCloseOperation(JFrameDISPOSE_ON_CLOSE);// 设置但关闭窗体时退出程序 

    setSize(iWidth, iHeight);// 设置窗体大小 

    int w = getSize()width;// 获取窗体宽度 

    int h = getSize()height;// 获取窗体高度 

    Systemoutprintln("窗体宽:" + w + " 窗体高:" + h); 

    int x = (dimwidth - w) / 2; 

    int y = (dimheight - h) / 2; 

    setLocation(x, y);// 将窗体移到屏幕中间 

    setVisible(true);// 显示窗体 

    }

    public static void main(String[] args) { 

    JFramesetDefaultLookAndFeelDecorated(true);// 使用最新的SWING外观 

    new mainFrame("main Frame Demo", 400, 300); 

    } 

程序员面试题精选(36中等难度) 

(01)将二元查找树转变成排序的双向链表

  题目:输入1棵二元查找树,将该二元查找树转换成1个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。

  比如将二元查找树

                                            10

                                          /    \

                                        6       14

                                      /  \     /  \

                                   4     8  12   16

转换成双向链表

4=6=8=10=12=14=16。

  分析:本题是微软的面试题。很多与树相关的题目都是用递归的思路来解决,本题也不例外。下面我们用两种不同的递归思路来分析。

  思路1:当我们到达某1结点准备调整以该结点为根结点的子树时,先调整其左子树将左子树转换成1个排好序的左子链表,再调整其右子树转换右子链表。最近链接左子链表的最右结点(左子树的最大结点)、当前结点和右子链表的最左结点(右子树的最小结点)。从树的根结点开始递归调整所有结点。

  思路二:我们可以中序遍历整棵树。按照这个方式遍历树,比较小的结点先访问。如果我们每访问1个结点,假设之前访问过的结点已经调整成1个排序双向链表,我们再将调整当前结点的指针将其链接到链表的末尾。当所有结点都访问过之后,整棵树也就转换成1个排序双向链表了。

参考代码:

首先我们定义二元查找树结点的数据结构如下:

    struct BSTreeNode // a node in the binary search tree

    {

 int          m_nValue; // value of node

BSTreeNode  *m_pLeft;  // left child of node

BSTreeNode  *m_pRight; // right child of node

    };

思路1对应的代码:

///////////////////////////////////////////////////////////////////////

// Covert a sub binary-search-tree into a sorted double-linked list

// Input: pNode - the head of the sub tree

//        asRight - whether pNode is the right child of its parent

// Output: if asRight is true, return the least node in the sub-tree

//         else return the greatest node in the sub-tree

///////////////////////////////////////////////////////////////////////

BSTreeNode* ConvertNode(BSTreeNode* pNode, bool asRight)

{

if(!pNode)

return NULL;

 

BSTreeNode *pLeft = NULL;

BSTreeNode *pRight = NULL;

 

// Convert the left sub-tree

if(pNode->m_pLeft)

pLeft = ConvertNode(pNode->m_pLeft, false);

 

// Connect the greatest node in the left sub-tree to the current node

if(pLeft)

{

pLeft->m_pRight = pNode;

pNode->m_pLeft = pLeft;

}

 

// Convert the right sub-tree

if(pNode->m_pRight)

pRight = ConvertNode(pNode->m_pRight, true);

 

// Connect the least node in the right sub-tree to the current node

if(pRight)

{

pNode->m_pRight = pRight;

pRight->m_pLeft = pNode;

}

 

BSTreeNode *pTemp = pNode;

 

// If the current node is the right child of its parent, 

// return the least node in the tree whose root is the current node

if(asRight)

{

while(pTemp->m_pLeft)

pTemp = pTemp->m_pLeft;

}

// If the current node is the left child of its parent, 

// return the greatest node in the tree whose root is the current node

else

{

while(pTemp->m_pRight)

pTemp = pTemp->m_pRight;

}

 

return pTemp;

}

 

///////////////////////////////////////////////////////////////////////

// Covert a binary search tree into a sorted double-linked list

// Input: the head of tree

// Output: the head of sorted double-linked list

///////////////////////////////////////////////////////////////////////

BSTreeNode* Convert(BSTreeNode* pHeadOfTree)

{

// As we want to return the head of the sorted double-linked list,

// we set the second parameter to be true

return ConvertNode(pHeadOfTree, true);

}

思路二对应的代码:

///////////////////////////////////////////////////////////////////////

// Covert a sub binary-search-tree into a sorted double-linked list

// Input: pNode -           the head of the sub tree

//        pLastNodeInList - the tail of the double-linked list

///////////////////////////////////////////////////////////////////////

void ConvertNode(BSTreeNode* pNode, BSTreeNode*& pLastNodeInList)

{

if(pNode == NULL)

return;

 

BSTreeNode *pCurrent = pNode;

 

// Convert the left sub-tree

if (pCurrent->m_pLeft != NULL)

ConvertNode(pCurrent->m_pLeft, pLastNodeInList);

 

// Put the current node into the double-linked list

pCurrent->m_pLeft = pLastNodeInList; 

if(pLastNodeInList != NULL)

pLastNodeInList->m_pRight = pCurrent;

 

pLastNodeInList = pCurrent;

 

// Convert the right sub-tree

if (pCurrent->m_pRight != NULL)

ConvertNode(pCurrent->m_pRight, pLastNodeInList);

}

 

///////////////////////////////////////////////////////////////////////

// Covert a binary search tree into a sorted double-linked list

// Input: pHeadOfTree - the head of tree

// Output: the head of sorted double-linked list

///////////////////////////////////////////////////////////////////////

BSTreeNode* Convert_Solution1(BSTreeNode* pHeadOfTree)

{

BSTreeNode *pLastNodeInList = NULL;

ConvertNode(pHeadOfTree, pLastNodeInList);

 

// Get the head of the double-linked list

BSTreeNode *pHeadOfList = pLastNodeInList;

while(pHeadOfList && pHeadOfList->m_pLeft)

pHeadOfList = pHeadOfList->m_pLeft;

 

return pHeadOfList;

}

(02)设计包含min函数的栈

题目:定义栈的数据结构,要求添加1min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。 

分析:这是去年google的1道面试题。

我看到这道题目时,第1反应就是每次push1个新元素时,将栈里所有逆序元素排序。这样栈顶元素将是最小元素。但由于不能保证最后push进栈的元素最先出栈,这种思路设计的数据结构已经不是1个栈了。

在栈里添加1个成员变量存放最小元素(或最小元素的位置)。每次push1个新元素进栈的时候,如果该元素比当前的最小元素还要小,则更新最小元素。

1看这样思路挺好的。但仔细1想,该思路存在1个重要的问题:如果当前最小元素被pop出去,如何才能得到下1个最小元素?

因此仅仅只添加1个成员变量存放最小元素(或最小元素的位置)是不够的。我们需要1个辅助栈。每次push1个新元素的时候,同时将最小元素(或最小元素的位置。考虑到栈元素的类型可能是复杂的数据结构,用最小元素的位置将能减少空间消耗)push到辅助栈中;每次pop1个元素出栈的时候,同时pop辅助栈。

参考代码:

#include <deque>

#include <asserth>

 

template <typename T> class CStackWithMin

{

public:

CStackWithMin(void) {}

virtual ~CStackWithMin(void) {}

 

T& top(void);

const T& top(voidconst;

 

void push(const T& value);

void pop(void);

 

const T& min(voidconst;

 

private:

T>m_data;// theelements of stack

size_t>m_minIndex;// the indicesof minimum elements

};

 

// get the last element of mutable stack

template <typename T> T& CStackWithMin<T>::top()

{

return m_databack();

}

 

// get the last element of non-mutable stack

template <typename T> const T& CStackWithMin<T>::top() const

{

return m_databack();

}

 

// insert an elment at the end of stack

template <typename T> void CStackWithMin<T>::push(const T& value)

{

// append the data into the end of m_data

m_datapush_back(value);

 

// set the index of minimum elment in m_data at the end of m_minIndex

if(m_minIndexsize() == 0)

m_minIndexpush_back(0);

else

{

if(value < m_data[m_minIndexback()])

m_minIndexpush_back(m_datasize() - 1);

else

m_minIndexpush_back(m_minIndexback());

}

}

 

// erease the element at the end of stack

template <typename T> void CStackWithMin<T>::pop()

{

// pop m_data

m_datapop_back();

 

// pop m_minIndex

m_minIndexpop_back();

}

 

// get the minimum element of stack

template <typename T> const T& CStackWithMin<T>::min() const

{

assert(m_datasize() > 0);

assert(m_minIndexsize() > 0);

 

return m_data[m_minIndexback()];

}

举个例子演示上述代码的运行过程:

  步骤              数据栈            辅助栈                最小值

1push 3    3          0             3

2push 4    3,4        0,0           3

3push 2    3,4,2      0,0,2         2

4push 1    3,4,2,1    0,0,2,3       1

5pop       3,4,2      0,0,2         2

6pop       3,4        0,0           3

7push 0    3,4,0      0,0,2         0

讨论:如果思路正确,编写上述代码不是1件很难的事情。但如果能注意1些细节无疑能在面试中加分。比如我在上面的代码中做了如下的工作:

·         用模板类实现。如果别人的元素类型只是int类型,模板将能给面试官带来好印象;

·         两个版本的top函数。在很多类中,都需要提供const和非const版本的成员访问函数;

·         min函数中assert。将代码写的尽量安全是每个软件公司对程序员的要求;

·         添加1些注释。注释既能提高代码的可读性,又能增加代码量,何乐而不为?

总之,在面试时如果时间允许,尽量将代码写的漂亮1些。说不定代码中的几个小亮点就能让自己轻松拿到心仪的Offer

(03) 求子数组的最大和

   [折叠] 

 

题目:输入1个整形数组,数组里有正数也有负数。数组中连续的1个或多个整数组成1个子数组,每个子数组都有1个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。

示例输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18。

分析:本题最初为2005年浙江大学计算机系的考研题的最后1道程序设计题,在2006年里包括google在内的很多知名公司都将本题当作面试题。由于本题在网络中广为流传,本题也顺利成为2006年程序员面试题中经典中的经典。

如果不考虑时间复杂度,我们可以枚举出所有子数组并求出他们的和。不过非常遗憾的是,由于长度为n的数组有O(n2)个子数组;而且求1个长度为n的数组的和的时间复杂度为O(n)。因此这种思路的时间是O(n3)。

很容易理解,当我们加上1个正数时,和会增加;当我们加上1个负数时,和会减少。如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零,不然的话这个负数将会减少接下来的和。基于这样的思路,我们可以写出如下代码。

参考代码:

/////////////////////////////////////////////////////////////////////////////

// Find the greatest sum of all sub-arrays

// Return value: if the input is valid, return true, otherwise return false

/////////////////////////////////////////////////////////////////////////////

bool FindGreatestSumOfSubArray

(

int *pData,           // an array

unsigned int nLength, // the length of array

int &nGreatestSum     // the greatest sum of all sub-arrays

)

{

// if the input is invalid, return false

if((pData == NULL) || (nLength == 0))

return false;

 

int nCurSum = nGreatestSum = 0;

for(unsigned int i = 0; i < nLength; ++i)

{

nCurSum += pData[i];

 

// if the current sum is negative, discard it

if(nCurSum < 0)

nCurSum = 0;

 

// if a greater sum is found, update the greatest sum

if(nCurSum > nGreatestSum)

nGreatestSum = nCurSum;

}

 

// if all data are negative, find the greatest element in the array

if(nGreatestSum == 0)

{

nGreatestSum = pData[0];

for(unsigned int i = 1; i < nLength; ++i)

{

if(pData[i] > nGreatestSum)

nGreatestSum = pData[i];

}

}

 

return true;

讨论:上述代码中有两点值得和大家讨论1下:

·         函数的返回值不是子数组和的最大值,而是1个判断输入是否有效的标志。如果函数返回值的是子数组和的最大值,那么当输入1个空指针是应该返回什么呢?返回0?那这个函数的用户怎么区分输入无效和子数组和的最大值刚好是0这两中情况呢?基于这个考虑,本人认为将子数组和的最大值以引用的方式放到参数列表中,同时让函数返回1个函数是否正常执行的标志。

·         输入有1类特殊情况需要特殊处理。当输入数组中所有整数都是负数时,子数组和的最大值就是数组中的最大元素。

(04) 在二元树中找出和为某1值的所有路径   [折叠] 

题目:输入1个整数和1棵二元树。从树的根结点开始往下访问1直到叶结点所经过的所有结点形成1条路径。打印出和与输入整数相等的所有路径。

示例输入整数22和如下二元树

                                            10

                                           /   \

                                          5     12

                                        /   \   

                                      4     7  

则打印出两条路径:10, 12和10, 5, 7。

二元树结点的数据结构定义为:

struct BinaryTreeNode // a node in the binary tree

{

int              m_nValue; // value of node

BinaryTreeNode  *m_pLeft;  // left child of node

BinaryTreeNode  *m_pRight; // right child of node

};

分析:这是百度的1道笔试题,考查对树这种基本数据结构以及递归函数的理解。

当访问到某1结点时,将该结点添加到路径上,并累加当前结点的值。如果当前结点为叶结点并且当前路径的和刚好等于输入的整数,则当前的路径符合要求,我们将它打印出来。如果当前结点不是叶结点,则继续访问它的子结点。当前结点访问结束后,递归函数将自动回到父结点。因此我们在函数退出之前要在路径上删除当前结点并减去当前结点的值,以确保返回父结点时路径刚好是根结点到父结点的路径。我们不难看出保存路径的数据结构实际上是1个栈结构,因为路径要与递归调用状态1致,而递归调用本质就是1个压栈和出栈的过程。

参考代码:

///////////////////////////////////////////////////////////////////////

// Find paths whose sum equal to expected sum

///////////////////////////////////////////////////////////////////////

void FindPath

(

BinaryTreeNode*   pTreeNode,    // a node of binary tree

int               expectedSum,  // the expected sum

std::vector<int>&path,        // a pathfrom root to current node

int&              currentSum    // the sum of path

)

{

if(!pTreeNode)

return;

 

currentSum += pTreeNode->m_nValue;

pathpush_back(pTreeNode->m_nValue);

 

// if the node is a leaf, and the sum is same as pre-defined, 

// the path is what we want、 print the path

bool isLeaf = (!pTreeNode->m_pLeft && !pTreeNode->m_pRight);

if(currentSum == expectedSum && isLeaf)

{

std::vector<int>::iterator iter =pathbegin();

for(; iter != pathend(); ++ iter)

std::cout<<*iter<<'\t';

std::cout<<std::endl;

}

 

// if the node is not a leaf, goto its children

if(pTreeNode->m_pLeft)

FindPath(pTreeNode->m_pLeft, expectedSum, path, currentSum);

if(pTreeNode->m_pRight)

FindPath(pTreeNode->m_pRight, expectedSum, path, currentSum);

 

// when we finish visiting a node and return to its parent node,

// we should delete this node from the path and 

// minus the node's value from the current sum

currentSum -= pTreeNode->m_nValue; //!!I think here is no use

pathpop_back();

(05)查找最小的k个元素 [折叠]

题目:输入n个整数,输出其中最小的k个。

示例输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。

分析:这道题最简单的思路莫过于将输入的n个整数排序,这样排在最前面的k个数就是最小的k个数。只是这种思路的时间复杂度为O(nlogn)。我们试着寻找更快的解决思路。

我们可以开辟1个长度为k的数组。每次从输入的n个整数中读入1个数。如果数组中已经插入的元素少于k个,则将读入的整数直接放到数组中。否则长度为k的数组已经满了,不能再往数组里插入元素,只能替换了。如果读入的这个整数比数组中已有k个整数的最大值要小,则用读入的这个整数替换这个最大值;如果读入的整数比数组中已有k个整数的最大值还要大,则读入的这个整数不可能是最小的k个整数之1,抛弃这个整数。这种思路相当于只要排序k个整数,因此时间复杂可以降到O(n+nlogk)。通常情况下k要远小于n,所以这种办法要优于前面的思路。

这是我能够想出来的最快的解决方案。不过从给面试官留下更好印象的角度出发,我们可以进1步将代码写得更漂亮1些。从上面的分析,当长度为k的数组已经满了之后,如果需要替换,每次替换的都是数组中的最大值。在常用的数据结构中,能够在O(1)时间里得到最大值的数据结构为最大堆。因此我们可以用堆(heap)来代替数组。

另外,自己重头开始写1个最大堆需要1定量的代码。我们现在不需要重新去发明车轮,因为前人早就发明出来了。同样,STL中的set和multiset为我们做了很好的堆的实现,我们可以拿过来用。既偷了懒,又给面试官留下熟悉STL的好印象,何乐而不为之?

参考代码:

#include <set>

#include <vector>

#include <iostream>

 

using namespace std;

 

typedef multiset<int, greater<int> >  IntHeap;

 

///////////////////////////////////////////////////////////////////////

// find k least numbers in a vector

///////////////////////////////////////////////////////////////////////

void FindKLeastNumbers

(

const vector<int>& data,               // a vector of data

IntHeap& leastNumbers,                 // k least numbers, output

unsigned int k                              

)

{

leastNumbersclear();

 

if(k == 0 || datasize() < k)

return;

 

vector<int>::const_iterator iter = databegin();

for(; iter != dataend(); ++ iter)

{

// if less than k numbers was inserted into leastNumbers

if((leastNumberssize()) < k)

leastNumbersinsert(*iter);

 

// leastNumbers contains k numbers and it's full now

else

{

// first number in leastNumbers is the greatest one

IntHeap::iterator iterFirst = leastNumbersbegin();

 

// if is less than the previous greatest number 

if(*iter < *(leastNumbersbegin()))

{

// replace the previous greatest number

leastNumberserase(iterFirst);

leastNumbersinsert(*iter);

}

}

}

}

(06)判断整数序列是不是二元查找树的后序遍历结果 

   [折叠] 

 

题目:输入1个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。如果是返回true,否则返回false。 

示例输入5、7、6、9、11、10、8,由于这1整数序列是如下树的后序遍历结果:

         8

       /  \

      6    10

    / \    / \

   5   7   9  11

因此返回true。

如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。

分析:这是1trilogy的笔试题,主要考查对二元查找树的理解。

在后续遍历得到的序列中,最后1个元素为树的根结点。从头开始扫描这个序列,比根结点小的元素都应该位于序列的左半部分;从第1个大于跟结点开始到跟结点前面的1个元素为止,所有元素都应该大于跟结点,因为这部分元素对应的是树的右子树。根据这样的划分,将序列划分为左右两部分,我们递归地确认序列的左、右两部分是不是都是二元查找树。

参考代码:

using namespace std;

 

///////////////////////////////////////////////////////////////////////

// Verify whether a squence of integers are the post order traversal

// of a binary search tree (BST)

// Input: squence - the squence of integers

//        length  - the length of squence

// Return: return ture if the squence is traversal result of a BST,

//         otherwise, return false

///////////////////////////////////////////////////////////////////////

bool verifySquenceOfBST(int squence[], int length)

{

if(squence == NULL || length <= 0)

return false;

 

// root of a BST is at the end of post order traversal squence

int root = squence[length - 1];

 

// the nodes in left sub-tree are less than the root

int i = 0;

for(; i < length - 1; ++ i)

{

if(squence[i] > root)

break;

}

 

// the nodes in the right sub-tree are greater than the root

int j = i;

for(; j < length - 1; ++ j)

{

if(squence[j] < root)

return false;

}

 

// verify whether the left sub-tree is a BST

bool left = true;

if(i > 0)

left = verifySquenceOfBST(squence, i);

 

// verify whether the right sub-tree is a BST

bool right = true;

if(i < length - 1)

right = verifySquenceOfBST(squence + i, length - i - 1);

 

return (left && right);

}

(07) 翻转句子中单词的顺序   [折叠] 

题目:输入1个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母1样处理。

示例输入“I am a student”,则输出“student、 a am I”。

分析:由于编写string相关代码能够反映程序员的编程能力和编程习惯,与string相关的问题1直是程序员笔试、面试题的热门题目。本题也曾多次受到包括微软在内的大量公司的青睐。

由于本题需要翻转句子,我们先颠倒句子中的所有字符。这时,不但翻转了句子中单词的顺序,而且单词内字符也被翻转了。我们再颠倒每个单词内的字符。由于单词内的字符被翻转两次,因此顺序仍然和输入时的顺序保持1致。

还是以上面的输入为例子。翻转“I am a student”中所有字符得到“、tneduts a ma I”,再翻转每个单词中字符的顺序得到“students、 a am I”,正是符合要求的输出。

参考代码:

///////////////////////////////////////////////////////////////////////

// Reverse a string between two pointers

// Input: pBegin - the begin pointer in a string

//        pEnd   - the end pointer in a string

///////////////////////////////////////////////////////////////////////

void Reverse(char *pBegin, char *pEnd)

{

if(pBegin == NULL || pEnd == NULL)

return;

 

while(pBegin < pEnd)

{

char temp = *pBegin;

*pBegin = *pEnd;

*pEnd = temp;

 

pBegin ++, pEnd --;

}

}

 

///////////////////////////////////////////////////////////////////////

// Reverse the word order in a sentence, but maintain the character

// order inside a word

// Input: pData - the sentence to be reversed

///////////////////////////////////////////////////////////////////////

char* ReverseSentence(char *pData)

{

if(pData == NULL)

return NULL;

 

char *pBegin = pData;

char *pEnd = pData;

 

while(*pEnd != '\0')

pEnd ++;

pEnd--;

 

// Reverse the whole sentence

Reverse(pBegin, pEnd);

 

// Reverse every word in the sentence

pBegin = pEnd = pData;

while(*pBegin != '\0')

{

if(*pBegin == ' ')

{

pBegin ++;

pEnd ++;

continue;

}

// A word is between with pBegin and pEnd, reverse it

else if(*pEnd == ' ' || *pEnd == '\0')

{

Reverse(pBegin, --pEnd);

pBegin = ++pEnd;

}

else

{

pEnd ++;

}

}

 

return pData;

}

(08) 1+2+、、、+n

题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。

分析:这道题没有多少实际意义,因为在软件开发中不会有这么变态的限制。但这道题却能有效地考查发散思维能力,而发散思维能力能反映出对编程相关技术理解的深刻程度。

通常求1+2+…+n除了用公式n(n+1)/2之外,无外乎循环和递归两种思路。由于已经明确限制for和while的使用,循环已经不能再用了。同样,递归函数也需要用if语句或者条件判断语句来判断是继续递归下去还是终止递归,但现在题目已经不允许使用这两种语句了。

我们仍然围绕循环做文章。循环只是让相同的代码执行n遍而已,我们完全可以不用for和while达到这个效果。比如定义1个类,我们new1含有n个这种类型元素的数组,那么该类的构造函数将确定会被调用n次。我们可以将需要执行的代码放到构造函数里。如下代码正是基于这个思路:

class Temp

{

public:

Temp() { ++ N; Sum += N; }

 

static void Reset() { N = 0; Sum = 0; }

static int GetSum() { return Sum; }

 

private:

static int N;

static int Sum;

};

 

int Temp::N = 0;

int Temp::Sum = 0;

 

int solution1_Sum(int n)

{

      Temp::Reset();

 

Temp *a = new Temp[n];

delete []a;

a = 0;

 

      return Temp::GetSum();

}

我们同样也可以围绕递归做文章。既然不能判断是不是应该终止递归,我们不妨定义两个函数。1个函数充当递归函数的角色,另1个函数处理终止递归的情况,我们需要做的就是在两个函数里二选1。从二选1我们很自然的想到布尔变量,比如ture(1)的时候调用第1个函数,false(0)的时候调用第2个函数。那现在的问题是如和将数值变量n转换成布尔值。如果对n连续做两次反运算,即!!n,那么非零的n转换为true,0转换为false。有了上述分析,我们再来看下面的代码:

class A;

A* Array[2];

 

class A

{

public:

virtual int Sum (int n) { return 0; }

};

 

class B: public A

{

public:

virtual int Sum (int n) { return Array[!!n]->Sum(n-1)+n; }

};

 

int solution2_Sum(int n)

{

A a;

B b;

Array[0] = &a;

Array[1] = &b;

 

int value = Array[1]->Sum(n);

 

return value;

}

这种方法是用虚函数来实现函数的选择。当n不为零时,执行函数B::Sum;当n为0时,执行A::Sum。我们也可以直接用函数指针数组,这样可能还更直接1些:

typedef int (*fun)(int);

 

int solution3_f1(int i) 

{

return 0;

}

 

int solution3_f2(int i)

{

fun f[2]={solution3_f1, solution3_f2}; 

return i+f[!!i](i-1);

}

另外我们还可以让编译器帮我们来完成类似于递归的运算,比如如下代码:

template <int n> struct solution4_Sum

{

enum Value { N = solution4_Sum<n - 1>::N + n};

};

template <> struct solution4_Sum<1>

{

enum Value { N = 1};

};

solution4_Sum<100>::N就是1+2+、、、+100的结果。当编译器看到solution4_Sum<100>时,就是为模板类solution4_Sum以参数100生成该类型的代码。但以100为参数的类型需要得到以99为参数的类型,因为solution4_Sum<100>::N=solution4_Sum<99>::N+100。这个过程会递归1直到参数为1的类型,由于该类型已经显式定义,编译器无需生成,递归编译到此结束。由于这个过程是在编译过程中完成的,因此要求输入n必须是在编译期间就能确定,不能动态输入。这是该方法最大的缺点。而且编译器对递归编译代码的递归深度是有限制的,也就是要求n不能太大。

大家还有更多、更巧妙的思路吗?欢迎讨论^_^

(09) 查找链表中倒数第k个结点

题目:输入1个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。链表结点定义如下: 

struct ListNode

{

int       m_nKey;

ListNode* m_pNext;

};

分析:为了得到倒数第k个结点,很自然的想法是先走到链表的尾端,再从尾端回溯k步。可是输入的是单向链表,只有从前往后的指针而没有从后往前的指针。因此我们需要打开我们的思路。

既然不能从尾结点开始遍历这个链表,我们还是将思路回到头结点上来。假设整个链表有n个结点,那么倒数第k个结点是从头结点开始的第n-k-1个结点(从0开始计数)。如果我们能够得到链表中结点的个数n,那我们只要从头结点开始往后走n-k-1步就可以了。如何得到结点数n?这个不难,只需要从头开始遍历链表,每经过1个结点,计数器加1就行了。

这种思路的时间复杂度是O(n),但需要遍历链表两次。第1次得到链表中结点个数n,第2次得到从头结点开始的第n-k-1个结点即倒数第k个结点。

如果链表的结点数不多,这是1种很好的方法。但如果输入的链表的结点个数很多,有可能不能1次性将整个链表都从硬盘读入物理内存,那么遍历两遍意味着1个结点需要两次从硬盘读入到物理内存。我们知道将数据从硬盘读入到内存是非常耗时间的操作。我们能不能将链表遍历的次数减少到1?如果可以,将能有效地提高代码执行的时间效率。

如果我们在遍历时维持两个指针,第1个指针从链表的头指针开始遍历,在第k-1步之前,第2个指针保持不动;在第k-1步开始,第2个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第1个(走在前面的)指针到达链表的尾结点时,第2个指针(走在后面的)指针正好是倒数第k个结点。

这种思路只需要遍历链表1次。对于很长的链表,只需要将每个结点从硬盘导入到内存1次。因此这1方法的时间效率前面的方法要高。

思路1的参考代码:

///////////////////////////////////////////////////////////////////////

// Find the kth node from the tail of a list

// Input: pListHead - the head of list

//        k         - the distance to the tail

// Output: the kth node from the tail of a list

///////////////////////////////////////////////////////////////////////

ListNode* FindKthToTail_Solution1(ListNode* pListHead, unsigned int k)

{

if(pListHead == NULL)

return NULL;

 

// count the nodes number in the list

ListNode *pCur = pListHead;

unsigned int nNum = 0;

while(pCur->m_pNext != NULL)

{

pCur = pCur->m_pNext;

nNum ++;

}

 

// if the number of nodes in the list is less than k

// do nothing

if(nNum < k)

return NULL;

 

// the kth node from the tail of a list 

// is the (n - k)th node from the head

pCur = pListHead;

for(unsigned int i = 0; i < nNum - k; ++ i)

pCur = pCur->m_pNext;

 

  return pCur;

}

思路二的参考代码:

///////////////////////////////////////////////////////////////////////

// Find the kth node from the tail of a list

// Input: pListHead - the head of list

//        k         - the distance to the tail

// Output: the kth node from the tail of a list

///////////////////////////////////////////////////////////////////////

ListNode* FindKthToTail_Solution2(ListNode* pListHead, unsigned int k)

{

if(pListHead == NULL)

return NULL;

 

ListNode *pAhead = pListHead;

ListNode *pBehind = NULL;

 

for(unsigned int i = 0; i < k; ++ i)

{

if(pAhead->m_pNext != NULL)

pAhead = pAhead->m_pNext;

else

{

// if the number of nodes in the list is less than k, 

// do nothing

return NULL;

}

}

 

pBehind = pListHead;

 

// the distance between pAhead and pBehind is k

// when pAhead arrives at the tail, p

// Behind is at the kth node from the tail

while(pAhead->m_pNext != NULL)

{

pAhead = pAhead->m_pNext;

pBehind = pBehind->m_pNext;

}

 

return pBehind;

}

讨论:这道题的代码有大量的指针操作。在软件开发中,错误的指针操作是大部分问题的根源。因此每个公司都希望程序员在操作指针时有良好的习惯,比如使用指针之前判断是不是空指针。这些都是编程的细节,但如果这些细节将握得不好,很有可能就会和心仪的公司失之交臂。

另外,这两种思路对应的代码都含有循环。含有循环的代码经常出的问题是在循环结束条件的判断。是该用小于还是小于等于?是该用k还是该用k-1?由于题目要求的是从0开始计数,而我们的习惯思维是从1开始计数,因此首先要想好这些边界条件再开始编写代码,再者要在编写完代码之后再用边界值、边界值减1、边界值加1都运行1次(在纸上写代码就只能在心里运行了)。

扩展:和这道题类似的题目还有:输入1个单向链表。如果该链表的结点数为奇数,输出中间的结点;如果链表结点数为偶数,输出中间两个结点前面的1个。如果各位感兴趣,请自己分析并编写代码。

(10) 在排序数组中查找和为给定值的两个数字

题目:输入1个已经按升序排序过的数组和1个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意1对即可。

示例输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。

分析:如果我们不考虑时间复杂度,最简单想法的莫过去先在数组中固定1个数字,再依次判断数组中剩下的n-1个数字与它的和是不是等于输入的数字。可惜这种思路需要的时间复杂度是O(n2)。

我们假设现在随便在数组中找到两个数。如果它们的和等于输入的数字,那太好了,我们找到了要找的两个数字;如果小于输入的数字呢?我们希望两个数字的和再大1点。由于数组已经排好序了,我们是不是可以将较小的数字的往后面移动1个数字?因为排在后面的数字要大1些,那么两个数字的和也要大1些,就有可能等于输入的数字了;同样,当两个数字的和大于输入的数字的时候,我们将较大的数字往前移动,因为排在数组前面的数字要小1些,它们的和就有可能等于输入的数字了。

我们将前面的思路整理1下:最初我们找到数组的第1个数字和最后1个数字。当两个数字的和大于输入的数字时,将较大的数字往前移动;当两个数字的和小于数字时,将较小的数字往后移动;当相等时,打完收工。这样扫描的顺序是从数组的两端向数组的中间扫描。

问题是这样的思路是不是正确的呢?这需要严格的数学证明。感兴趣的读者可以自行证明1下。

参考代码:

///////////////////////////////////////////////////////////////////////

// Find two numbers with a sum in a sorted array

// Output: ture is found such two numbers, otherwise false

///////////////////////////////////////////////////////////////////////

bool FindTwoNumbersWithSum

(

int data[],           // a sorted array

unsigned int length,  // the length of the sorted array   

int sum,              // the sum

int& num1,            // the first number, output

int& num2             // the second number, output

)

{

bool found = false;

if(length < 1)

return found;

 

int ahead = length - 1;

int behind = 0;

 

while(ahead > behind)

{

long long curSum = data[ahead] + data[behind];

 

// if the sum of two numbers is equal to the input

// we have found them

if(curSum == sum)

{

num1 = data[behind];

num2 = data[ahead];

found = true;

break;

}

// if the sum of two numbers is greater than the input

// decrease the greater number

else if(curSum > sum)

ahead --;

// if the sum of two numbers is less than the input

// increase the less number

else

behind ++;

}

 

return found;

}

扩展:如果输入的数组是没有排序的,但知道里面数字的范围,其他条件不变,如和在O(n)时间里找到这两个数字?

(11) 求二元查找树的镜像

题目:输入1颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。 

示例输入:

     8

    /  \

  6      10

 /\       /\

5  7    9   11

输出:

      8

    /  \

  10    6

 /\      /\

11  9  7  5

定义二元查找树的结点为:

struct BSTreeNode // a node in the binary search tree (BST)

{

int          m_nValue; // value of node

BSTreeNode  *m_pLeft;  // left child of node

BSTreeNode  *m_pRight; // right child of node

};

分析:尽管我们可能1下子不能理解镜像是什么意思,但上面的例子给我们的直观感觉,就是交换结点的左右子树。我们试着在遍历例子中的二元查找树的同时来交换每个结点的左右子树。遍历时首先访问头结点8,我们交换它的左右子树得到:

      8

    /  \

  10    6

 /\      /\

9  11  5  7

我们发现两个结点6和10的左右子树仍然是左结点的值小于右结点的值,我们再试着交换他们的左右子树,得到:

      8

    /  \

  10    6

 /\      /\

11  9  7   5

刚好就是要求的输出。

上面的分析印证了我们的直觉:在遍历二元查找树时每访问到1个结点,交换它的左右子树。这种思路用递归不难实现,将遍历二元查找树的代码稍作修改就可以了。参考代码如下:

///////////////////////////////////////////////////////////////////////

// Mirror a BST (swap the left right child of each node) recursively

// the head of BST in initial call

///////////////////////////////////////////////////////////////////////

void MirrorRecursively(BSTreeNode *pNode)

{

if(!pNode)

return;

 

// swap the right and left child sub-tree

BSTreeNode *pTemp = pNode->m_pLeft;

pNode->m_pLeft = pNode->m_pRight;

pNode->m_pRight = pTemp;

// mirror left child sub-tree if not null

if(pNode->m_pLeft)

MirrorRecursively(pNode->m_pLeft);  

 

// mirror right child sub-tree if not null

if(pNode->m_pRight)

MirrorRecursively(pNode->m_pRight); 

}

由于递归的本质是编译器生成了1个函数调用的栈,因此用循环来完成同样任务时最简单的办法就是用1个辅助栈来模拟递归。首先我们将树的头结点放入栈中。在循环中,只要栈不为空,弹出栈的栈顶结点,交换它的左右子树。如果它有左子树,将它的左子树压入栈中;如果它有右子树,将它的右子树压入栈中。这样在下次循环中就能交换它儿子结点的左右子树了。参考代码如下:

///////////////////////////////////////////////////////////////////////

// Mirror a BST (swap the left right child of each node) Iteratively

// Input: pTreeHead: the head of BST

///////////////////////////////////////////////////////////////////////

void MirrorIteratively(BSTreeNode *pTreeHead)

{

if(!pTreeHead)

return;

 

std::stack<BSTreeNode*>stackTreeNode;

stackTreeNodepush(pTreeHead);

 

while(stackTreeNodesize())

{

BSTreeNode *pNode = stackTreeNodetop();

stackTreeNodepop();

 

// swap the right and left child sub-tree

BSTreeNode *pTemp = pNode->m_pLeft;

pNode->m_pLeft = pNode->m_pRight;

pNode->m_pRight = pTemp;

 

// push left child sub-tree into stack if not null

if(pNode->m_pLeft)

stackTreeNodepush(pNode->m_pLeft);

 

// push right child sub-tree into stack if not null

if(pNode->m_pRight)

stackTreeNodepush(pNode->m_pRight);

}

}

(12) 从上往下遍历二元树

 题目:输入1颗二元树,从上往下按层打印树的每个结点,同1层中按照从左往右的顺序打印。 

示例输入

      8

    /  \

   6    10

  /\     /\

 5  7   9  11

输出8   6   10   5   7   9   11

分析:这曾是微软的1道面试题。这道题实质上是要求遍历1棵二元树,只不过不是我们熟悉的前序、中序或者后序遍历。

我们从树的根结点开始分析。自然先应该打印根结点8,同时为了下次能够打印8的两个子结点,我们应该在遍历到8时将子结点6和10保存到1个数据容器中。现在数据容器中就有两个元素6 和10了。按照从左往右的要求,我们先取出6访问。打印6的同时要将6的两个子结点5和7放入数据容器中,此时数据容器中有三个元素10、5和7。接下来我们应该从数据容器中取出结点10访问了。注意10比5和7先放入容器,此时又比5和7先取出,就是我们通常说的先入先出。因此不难看出这个数据容器的类型应该是个队列。

既然已经确定数据容器是1个队列,现在的问题变成怎么实现队列了。实际上我们无需自己动手实现1个,因为STL已经为我们实现了1个很好的deque(两端都可以进出的队列),我们只需要拿过来用就可以了。

我们知道树是图的1种特殊退化形式。同时如果对图的深度优先遍历和广度优先遍历有比较深刻的理解,将不难看出这种遍历方式实际上是1种广度优先遍历。因此这道题的本质是在二元树上实现广度优先遍历。

参考代码:

#include <deque>

#include <iostream>

using namespace std;

 

struct BTreeNode // a node in the binary tree

{

int         m_nValue; // value of node

BTreeNode  *m_pLeft;  // left child of node

BTreeNode  *m_pRight; // right child of node

};

 

///////////////////////////////////////////////////////////////////////

// 

你可能感兴趣的:(算法)