1
老师想知道从某某同学当中,分数最高的是多少,现在请你编程模拟老师的询问。当然,老师有时候需要更新某位同学的成绩.
思路:
①区间最大值,点更新。
这里是最简单的,其实还有区间求和,区间最大值,区间最小值,点更新,区间更新。
可以用线段树、树状数组、RMQ
①这里只简单说明一下区间最大值和点更新,剩余的放在下一个篇详细介绍。
②就用线段树吧,n个数据,就是n个叶子节点存放数据。父节点表示范围的最大值,每次修改之后需要向上更新。
③如何建树?
线段树,build(1,1,n)递归建树,当节点的l==r的时候,递归结束,叶子节点(这里的l和r不是左右子树而是左右覆盖范围),依次得到的叶子节点肯定是从左到右的(8-->9-->5-->6-->7)。l和r可以表示输入数据的下标,就是覆盖范围嘛。更新点的值比更新区间的值要简单,查到点只需要向上更新即可。
代码:
#include
#define N 30005
struct node{
int l; //节点左覆盖范围
int r; //节点右覆盖范围
int value; //覆盖范围的最大值
}p[N*2];
int a[N]; //输入数据
int max(int a,int b){
return a>b?a:b;
}
void build(int o,int l,int r){
p[o].l=l;
p[o].r=r;
if(l==r) { //叶子节点
p[o].value=a[l];
return;
}
int mid=(l+r)/2;
build(o*2,l,mid);
build(o*2+1,mid+1,r);
p[o].value=max(p[o*2].value,p[o*2+1].value);
}
//从根节点开始查
int Find(int o,int l,int r){
if(p[o].l==l&&p[o].r==r){
return p[o].value;
}
//左儿子的右覆盖范围 小于 l (在右子树)
if(l>p[o*2].r) return Find(o*2+1,l,r);
//右儿子的左覆盖范围 大于 r (在左子树)
else if(rx2){
int xx=x1;
x1=x2;
x2=xx;
}
printf("%d\n",Find(1,x1,x2));
}else{
update(1,x1,x2);
}
}
}
return 0;
}
2
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
3.输入的文件可能带路径,记录文件名称不能带路径
思路
①首先字符串处理,有一个转义符误区,得到文件名和行数。然后定义一个map就行相同文件名和行数进行统计,map插入会改变输入顺序,这是第二个误区,需要一个辅助记录输入顺序。最后map转化结构题数组,进行结构体排序。
②结构体排序可以用sort和qsort,但是在本案例中qsort不能通过,我也不知什么个情况,注意cmp函数的返回会值(二者不同),已及决定升降序排序(刚好相反)。
③第一次提交答案错误,给出输出是中间是空格,其实不是,就是一个一行(坑了好久)。
代码
#include
#include
#include
#include
#include
#include
#include
3
扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A,2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王):)
3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
输入两手牌,两手牌之间用“-”连接,每手牌的每张牌以空格分隔,“-”两边没有空格,如:4 4 4 4-joker JOKER
请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR
基本规则:
(1)输入每手牌可能是个子,对子,顺子(连续5张),三个,炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子)
(3)大小规则跟大家平时了解的常见规则相同,个子,对子,三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;
(4)输入的两手牌不会出现相等的情况。
答案提示:
(1)除了炸弹和对王之外,其他必须同类型比较。
(2)输入已经保证合法性,不用检查输入是否是合法的牌。
(3)输入的顺子已经经过从小到大排序,因此不用再排序了.
思路
①首先明确告诉你,出的牌必须合法,单个,对子,顺子,三个,炸弹
②以上五种情况进行排列组合,要么有一方赢,要么组合错误(如单个--对子)
③一种情况是牌数相同,只需要比较第一位即可(不会相等,顺子排好序了)
在一副牌中,都为1的时候是单个,都为2的时候是对子,都为三的时候是三个,都为4的时候是炸弹,都大于等于5的时候是顺子。
④一种情况是牌数不等,一方是炸弹(两种类型,王砸和其它炸),要不然是ERROR。
注意:比如长度是4,那么一定是炸弹(只有炸弹才一次出4张),比如长度是2,要么是对子,要么是王炸。
代码
public class Main {
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
String str=cin.nextLine();
String[] Array=str.split("-");
String[] A=Array[0].split(" ");
String[] B=Array[1].split(" ");
int[] AA=new int[A.length];
int[] BB=new int[B.length];
for(int i=0;i(BB[0])) {
System.out.println(Array[0]);
}else {
System.out.println(Array[1]);
}
}
}
}