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

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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值