您的位置:首页 > 其它

16级西北工业大学ACM新生杯<第二次现场赛>

2016-12-25 10:57 344 查看
thinking:五个小时12题过了两题,真是悲哀,菜到没脾气,但我不会认输,我会把这当作动力,坚持下去。

the reason of failure:1、拿到题目看到E是模拟,果断开始写,大概40分钟写了,最后发现数据有些大,超时了,想了想并查集和哈希,但都不熟练,发现榜单A是签到就去做了。(复杂度判断能力弱,各种算法不熟练)

2、做题实在太慢,总是慢慢的想,难道就不能打字快点,速度思考抓紧时间吗,开头总是觉得时间多。

3、debug能力弱到爆炸,认真审题,认真审题,认真审题!!

Problem E: 灵魂链接

时间限制:1500MS 内存限制:65536KB

题意描述:

包子和老司机这一天在进行魔兽争霸3的对战,老司机使用兽族而包子使用不死族。老司机擅长使用白牛的灵魂链接和巫医的团补技能,灵魂链接就是将两个没有链接的单位链接起来共同承受伤害,团补技能就是对一个或者多个单位一定恢复生命值。现在老司机集齐了N个士兵准备进攻包子的基地,请你帮帮包子对抗邪恶的老司机!

 

输入:

首先输入一个正整数T,表示测试数据的组数。每一组测试数据,首先输入一个n和m,表示老司机派了n个士兵(编号为1~n)进攻包子的基地以及m个操作,最开始n个士兵都没有被链接。接下来输入n个数 ,表示n个士兵的初始生命值。然后输入m个操作,输入的操作可能是以下这几种:

(1)link xy:老司机使用白牛链接了第x个士兵以及第y个士兵;

(2)add1 xv:老司机对第x个士兵补充了v点生命值;

(3)add2 xv:老司机对第x个士兵及其链接的所有单位补充了v点生命值;

(4)add3 v:老司机对所有士兵补充了v点生命值;

(5)find1x:输出第x个士兵目前的生命值;

(6)find2x:输出第x个士兵所在的链接团体中生命值最少的士兵的生命值;

(7) find3:输出老司机目前军队中生命值最少的士兵生命值。

 

输出:

对于每组测试样例,首先输出一行“Case #x:”。接下来,对于该组样例中的每一个find类型的操作,输出相应的结果。

 

数据范围:

 

样例输入:

1

3 4

1 1 1

find1 1

link 1 2

add2 2 1

find3

 

样例输出:

Case #1:

1

1

thinking:

learning:1、对复杂度的判断,

2、后台数据的庞大,应该考虑赋值时候 sum=v*数据操作数

the reason of failure:

1、超时。

2、下标应该从0/1?开始,查找的时候与输入数据时候设置的下标不一样。

3、卡数据,即便指明v<=1000,min1赋值99999也是错误的,因为有300000条信息,赋值min1大于300000*1000才对。

中间出问题的代码需要找BUG。

#include <bits/stdc++.h>
using namespace std;
struct tree{
int weight,lch,rch;
}tree[333333];
int n,ggg,pre[333333];
void init(){
for(int i=1;i<=n;i++)
pre[i]=i;
}
int find(int x){
while(x!=pre[x])
x=pre[x];
return x;
}
int merge(int f1,int f2){
if(tree[f1].weight==0)return f2;
if(tree[f2].weight==0)return f1;
if(tree[f1].weight>tree[f2].weight)swap(f1,f2);
tree[f1].rch=merge(tree[f1].rch,f2);
swap(tree[f1].rch,tree[f1].lch);
return f1;
}
void link(int f1,int f2){
int x=find(f1),y=find(f2);
int gg;
gg=merge(x,y);
pre[f1]=pre[f2]=pre[x]=pre[y]=gg;
}
void add1(int f1,int f2){
// cout << f1 << endl;
tree[f1].weight+=f2;
}
void addd2(int f1,int f2){
// cout << f1 << "+" << f2 << endl;
tree[f1].weight+=f2;
if(tree[f1].rch!=0)addd2(tree[f1].rch,f2);
if(tree[f1].lch!=0)addd2(tree[f1].lch,f2);
}
void add2(int f1,int f2){
int x=find(f1);
addd2(x,f2);
}
void add3(int f1){
for(int i=1;i<=n;i++)
tree[i].weight+=f1;
}
void find1(int f1){
cout << tree[f1].weight+ggg << endl;
}
void find2(int f1){
cout << tree[find(f1)].weight+ggg << endl;
}
void find3(){
int minn=333333333;
for(int i=1;i<=n;i++)
if(tree[i].weight<minn)minn=tree[i].weight;
cout << minn+ggg << endl;
}
int main(){
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
int T,m,i,j,k,l,t1,t2,f1,f2;
char str1[20];
cin >> T;
int tt=T;
while(T--){
memset(tree,0,sizeof(tree));
ggg=0;
cin >> n >> m;
init();
for(i=1;i<=n;i++)
cin >> tree[i].weight;
while(m--){
cin >> str1;
//cout << tt-T<< "组" << m<< "\t "<< str1 << endl;
// cout << str1 << endl;
if(strcmp(str1,"link")==0){
// cin >> f1 >> f2;
cout << f1 <<" "<< f2 << endl;
link(f1,f2);
}else if(strcmp(str1,"add1")==0){
cin >> f1 >>f2;
// add1(f1,f2);
}else if(strcmp(str1,"add2")==0){
cin >> f1 >>f2;
// add2(f1,f2);
}else if(strcmp(str1,"add3")==0){
cin >> f1;
// ggg+=f1;
}else if(strcmp(str1,"find1")==0){
cin >> f1;
// find1(f1);
}else if(strcmp(str1,"find2")==0){
cin >> f1;
// find2(f1);
}else if(strcmp(str1,"find3")==0){
// find3();
}
}
}
return 0;
}

Problem I: 柱状图排序

时间限制:1000MS 内存限制:65536KB

题意描述:

柱状图是一种使用频率很高的统计图表,而一种常见的操作就是对柱状图中的各个项目的大小进行排序。现在请你实现这个功能。

 

输入:

首先输入一个正整数T,表示测试数据的组数。接下来T组数据,每组数据由m行长度相等的字符串 构成,表示一个柱状图。这些字符串的最后一行一定形如“ABC…”,每个大写英文字母表示柱状图的一个项目名;之前的每一行都由字符“#”和字符“$”构成,每一个“#”表示一个单位高度的矩形,“$”表示空格,某一项目名上的“#”越多则该项目的值就越大。输入数据保证是一个合法的柱状图,即每一个项目上都最多只有一段连续的“#”,形如一个长长的柱。

 

输出:

对于每组数据,首先输出一行“Case #x:”,其中x为测试样例的编号。接下来输出一个正整数n,占一行,表示这个柱状图中项目的个数。

然后按照值从大到小的顺序输出n行,每行形如“X num”,X是一个大写英文字母,表示一个项目名,num是这个项目的值。如果两个项目的值相同,则按项目名在字母表中的顺序输出。

 

样例输入:

2

$#$

$##

###

ABC

$$$$#

##$$#

##$##

#####

#####

ABCDE

 

样例输出:

Case #1:

3

B 3

C 2

A 1

Case #2:

5

E 5

A 4

B 4

D 3

C 2

 

样例解释:

在第一组样例中,A的值为1,B的值为3,C的值为2;在第二组样例中,A和B的值均为4,按照题意A排在B的前面。

 

样例解释:

在第一组样例中,A的值为1,B的值为3,C的值为2;在第二组样例中,A和B的值均为4,按照题意A排在B的前面。

thinking:

learning:1、可以使用gets(str1)进行读入,然后再判断

1、读题错误,题目要求的第一个输入的值是项目数而不是图的最高值。

2、读题错误,题目中的m>=1是指包括ABC在内的那一行,所以存在一组数据无$#的情况。

代码

#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
char t[30];
struct ttt{
int n,h;
}b[30];
int cmp1(const void *a,const void *b){
ttt c=(*(ttt*)a);
ttt d=(*(ttt*)b);
if(c.h==d.h)
return c.n-d.n;
else
return c.h-d.h;
}
bool walk[30];
int main(){//2、运行错误,运行错误也是可能超时
freopen("I_in.txt","r",stdin);
int length,cc1,cc2,cc3,n,i,j,k,T;
cin >> T;
int tt=T;
while(T--){
cout << "Case #" << tt-T << ":" << endl;
cc1=0;
cc2=0;
memset(walk,0,sizeof(walk));
while((cin >> t )&&(t[0]=='$'||t[0]=='#')){ //会存在for与while不进去的可能,请考虑这种情况
//  cout << t<< endl;
cc2++;
length=strlen(t);
for(i=0;i<length;i++){
if(t[i]=='#'&&walk[i]==0){ //1、数组中应该是i而不是0
walk[i]=1;
b[i].h=cc2;
//          cout << i <<cc2 << endl;
}

}
memset(t,0,sizeof(t));
}
//cout <<t << endl;
length=strlen(t);
for(i=0;i<length;i++)
b[i].n=i;
qsort(b,length,sizeof(ttt),cmp1);
cout << length << endl;
for(i=0;i<length;i++){
printf("%c ",b[i].n+65);
if(b[i].h!=0)cout << cc2-b[i].h+1 << endl;
else cout << b[i].h << endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: