2019浙江ACM省赛——部分题目

有一些题目过了我还没有重新写,先放一些我重新写好了的吧

签到题拿到了信心吧,9分钟写完两题,我们贼开心,我大哥说签到题有什么好开心的,如果不是我有一些地方卡了下,可能还是更快吧,还有就是测试案例多试了几个,不过这个是必须的。

现在回想当时比赛还是有点紧张,这个就是ACM的乐趣吧,感觉我今年就应该退役了,觉得下面的学弟都比我厉害多了,这两天搭个OJ给学弟们刷题用,训练还是要搞起来,平时的练习赛真的帮我们长了很多默契,特别是前面题目的时候我连看都没有看,直接上手就敲模板,然后学弟看完了直接报,速度抓起来了,信心也抓起来了。

这次比赛感谢大佬队友带飞,现在回顾了下排行榜拿的金奖还是运气好,在我们排名下面的做出来的速度都是比我们快,但是他们有罚时,我们一次AC(人品爆炸)

最后花了两个多小时写J题还是没有做出来,总的思路是对的,有一些细节的地方还是还没有想到,菜是原罪,现场也有两个专科组的做出来了,回来之后理了下看了下别人的题解,一下子就是写出来了。

G题

Lucky 7 in the Pocket

签到水题

题解:输入一个数字找比他大的最小那个数字能被7整除不能被4整除(直接写代码了,就不多解释了)

#include<bits/stdc++.h>
using namespace std;
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int n;
		scanf("%d",&n);
		for(int i=n;;i++){
			if(i%7==0 && i%4!=0){
				cout<<i<<endl;
				break;
			}
		}
	}
	
	
	return 0;
}

F题

Abbreviation

签到水题

题解:第一个不舍去,从第二个开始 包含 'a', 'e', 'i', 'y', 'o', 'u'  就不输出 很简单遍历一下就好了 这题因为我刚开始少打了个第一个字母还慢了差不多半分钟。罪过

#include<bits/stdc++.h>
using namespace std;
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		char num[1005];
		scanf("%s",&num);
		cout<<num[0];
		for(int i=1;i<strlen(num);i++){
			if(num[i]=='a' || num[i]== 'e' || num[i]=='i' || num[i]=='y'||num[i]=='o'||num[i]=='u'){
				continue;
			}
			cout<<num[i];
		}
		cout<<endl;
	}
	
	
	return 0;
}

E题

Sequence in the Pocket

思维题

题解:给你一组数字问你每一次选一个数字放在最前面,问你最少移动几次让他变成不下降序列。比如 2 2 3 3 4 或者1 2 3 4 5

给个新的数组,直接排序,然后从没有排序的数组那边从最大的开始往他的左边找,每一次按排好序的数组来求最长连续的序列长度写两个例子吧,可能说的不是很清楚

比如 3 4 5 1 2 这组数据的话就是先排好序 1 2 3 4 5 然后从最大的开始往左 那么就是5 4 3 就是有三个已经是符合排好序的标准了 那么我们只要去移动剩下的两个就好了 所以答案就是 5(数组长度)-2=3

再来一组 3 3 2 5 1 2 排好序后是 1 2 2 3 3 5 我们可以看出 3 3 5 在有没有排好的情况下 已经都是一样的了 所以只要减去排好的长度 就是答案 6-3 = 3

我大哥讲题的时候一下子没有听懂,就直接让他上去了打了,回来的时候我重新去整理了下思路,大哥就是大哥一下子就是想的那么快。

code:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int T;
	cin>>T;
	while(T--){
		int n;
		cin>>n;
		long long a[100055];
		long long b[100055];
		
		int maxIndex = -1;
		long long maxNum = -1;
		
		for(int i=0;i<n;i++){
			cin>>a[i];
			b[i]=a[i];
			if(maxNum<=a[i]){
				maxNum = a[i];
				maxIndex = i;
			}	
		}
		sort(b,b+n);
		int j = n-1;//最大的那个数字 
		long long sum = 0;
		for(int i=maxIndex;i>=0;i--){
			if(b[j]==a[i]){
				j--;
				sum++;
			}
		}
		cout<<n-sum<<endl;
	}
	
	
	return 0;
}

  

 

证明我是菜鸡的

Welcome Party

1,主要思路先建立关系,进行并查集的合并大的数字指向小的,合并完成后把那些指向自己的根给单独拿出来放入根的数组里面去

2.放好之后开始操作,用优先队列,这样就能解决了字符序的问题(当时想到了用队列,忘记了优先队列)

3.剩下的把指向他的逐一拿出来压入优先队列中会自动帮你处理字符序

#include<bits/stdc++.h>

using namespace std;
int root[1000055];
int find(int x){//找根 
	while(root[x]!=x){
		x = root[x];
	} 

	return x;
} 
void union1(int x,int y){
	int fx = find(x);
	int fy = find(y);
	if(fx<fy){
		root[fy]=fx;
	}
	else{
		root[fx]=fy;
	}
} 
int vis[1000005];//判断是不是放在答案的数组里面了
int ansCount = 0;
int ans[1000005];
vector<int> vv[1000005]; 
void bfs(int st){
	priority_queue<int,vector<int>,greater<int> > pq;
	pq.push(st);
	while(!pq.empty()){
		int cu = pq.top();
		pq.pop();
		if(vis[cu]==1) continue;//代表已经访问过了
		vis[cu]=1;
		ans[ansCount++] = cu;//添加进去
		for(int i=0;i<vv[cu].size();i++){
			int v = vv[cu][i];
			if(vis[v]!=1){
				pq.push(v); 
			}
		} 
		
	} 
} 
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		ansCount = 0;
		
		int n,m;
		scanf("%d %d",&n,&m);
		for(int i=0;i<=n;i++){
			vv[i].clear();
			vis[i]=0;
			root[i]=i;
		}
		for(int i=1;i<=m;i++){
			int a,b;
			scanf("%d %d",&a,&b);
			vv[a].push_back(b);
			vv[b].push_back(a);
			union1(a,b);
		}
		int ans1 = 0;
		for(int i=1;i<=n;i++){//如果是指向着自己那么就是根 
			if(root[i]==i){
				ans1++;
				vv[0].push_back(i);//把根全部加入到数组里面 
			}
		}
		bfs(0);
		cout<<ans1<<endl;
		for(int i=1;i<ansCount;i++){
			printf("%d",ans[i]);
			if(i==ansCount-1){
				printf("\n");
			}
			else{
				printf(" ");
			}
		}
		
		
	}
	
	
	
	return 0;
}

 

I 这题学弟找到了规律后来直接交给他了 用的Java的大数,还好练习赛的时候有大数题练了手 心惊胆战的过掉了 看了下大哥们的题解其实感觉可能当时后台的数据就是不是很好,仔细想想可能绿掉

Singing Everywhere

#include<bits/stdc++.h>
using namespace std;
int main(){
	int T;
	cin>>T;
	while(T--){
		long int num[100005];
		int n;
		cin>>n;
		
		for(int i=1;i<=n;i++){
			cin>>num[i];
			
		}	
		num[n+1]=99999999999;
		num[0]=99999999999;
		long long ansEnd = 0;
		for(int i=2;i<=n-1;i++){
			if(num[i]>num[i-1] && num[i]>num[i+1]){
				ansEnd++; 
			}
		}
		
		long long ans = 0;
		for(int i=2;i<=n-1;i++){
			long long notAns = 0;//没有删
			long long ansEd = 0;//删了的 
			if(num[i+1]>num[i-1] && num[i+1]>num[i+2]){
				ansEd++;
			}
			if(num[i-1]>num[i-2] && num[i-1]>num[i+1]){
				ansEd++;
			}
			if(num[i]>num[i-1] && num[i]>num[i+1]){
				notAns++;
			}
			if(num[i-1]>num[i-2] && num[i-1]>num[i]){
				notAns++;
			}
			if(num[i+1]>num[i+2] && num[i+1]>num[i]){
				notAns++;
			}
			
			if(ans<=notAns-ansEd){
				ans = notAns-ansEd;
			}
		}
		cout<<ansEnd-ans<<endl;
	}
	
	
	
	return 0;
} 

  

 

posted @ 2019-05-03 23:22  程序小白阿诺  阅读(1805)  评论(0编辑  收藏  举报