【ACM之旅】寒假集训(一)基础知识讲解

作为ACM小白一枚,参加了ACM爱好者协会的寒假集训。希望能够用博客记录每一天的生活和进步。

ACM之旅

第一天 基础知识讲解

博文目录

  • 今日感想
  • 题目C 元音字母 (唯一一道AC的题)
  • 题目E 从因数中找出来两个数 (差一点就AC的)

今日感想

一下子就上手C++感觉很不适应,做了几道题只AC了一道,成绩很一般,落差很大。
下面是题目总结。

题目C 元音字母 (唯一一道AC的题)

题目描述

We all know that a superhero can transform to certain other superheroes. But not all Superheroes can transform to any other superhero. A superhero with name s can transform to another superhero with name t if s can be made equal to t by changing any vowel in s to any other vowel and any consonant in s to any other consonant. Multiple changes can be made.
In this problem, we consider the letters ‘a’, ‘e’, ‘i’, ‘o’ and ‘u’ to be vowels and all the other letters to be consonants.
Given the names of two superheroes, determine if the superhero with name s can be transformed to the Superhero with name t.

输入

The first line contains the string s having length between 1 and 1000, inclusive.
The second line contains the string t having length between 1 and 1000, inclusive.
Both strings s and t are guaranteed to be different and consist of lowercase English letters only.

输出

Output “Yes” (without quotes) if the superhero with name s can be transformed to the superhero with name t and “No” (without quotes) otherwise.
You can print each letter in any case (upper or lower).

原思路

题目的意思就是元音和辅音相应位置是相对的。所以我建立了两个数组,然后我考虑,如果a这个是元音,那么b也是,否则退出,返回不是;如果a这个是辅音,b也必须不是元音,否则退出,返回不是;如果长度不等,直接退出,返回不是。

AC代码(写得不好,下面有改进代码)
#include <bits/stdc++.h>
using namespace std;

int main(){
	char voewl[]={'a','e','i','o','u'};
	char a[1001];
	char b[1001];
	int i=0;
	int j;
	int j_1;
	int result=0;
	int a_v=0;
	scanf("%s",a);
	scanf("%s",b);
	while(a[i]!='\0'){
		if(b[i]=='\0'){
			printf("no\n");
			return 0;
		}
		for(j=0;j<5;j++){
			if(a[i]==voewl[j]){
				a_v=1;
				for(j_1=0;j_1<5;j_1++){
					if(b[i]==voewl[j_1]){
						result=1;
						//Nothing to do
					} 
				}
				if(result==0){
					printf("no\n");
					return 0;
				}
			}
		}
		if(a_v==0){
			for(j_1=0;j_1<5;j_1++){
				if(b[i]==voewl[j_1]){
					printf("no\n");
					return 0;
				}
			}
		}
		i++;
		a_v=0;
		result=0;
	}
	if(a[i]=='\0'&&b[i]!='\0'){
		printf("no\n");
		return 0;
	}
	printf("yes\n");
	return 0;
}
思路优化

第一,不要用这么多循环去判断是不是。一个if,一个或,轻松搞定。
第二,两个是否同时为元音/辅音,可以用函数返回值进行判断。所以如果弄一个专门判断是元音还是辅音的函数,再加上inline,可以得到明显优化。
第三,判断长度用strlen。
下面的代码是参考学长的代码之后又改写的,思路清晰了很多,而且也简洁了很多。

优化代码
#include <bits/stdc++.h>
using namespace std;

inline int isVowel(char x){
	if(x=='a'||x=='e'||x=='i'||x=='o'||x=='u'){
		return 1;
	}
	return 0;
}

int main(){
	char a[1007];
	char b[1007];
	scanf("%s",a);
	scanf("%s",b);
	int a_length,b_length;
	int i=0;
	a_length=strlen(a);
	b_length=strlen(b);
	if(a_length!=b_length){
		printf("no\n");
		return 0;
	}
	for(i=0;a[i]!='\0';i++){
		if(isVowel(a[i])!=isVowel(b[i])){
			printf("no\n");
			return 0;
		}
	}
	printf("yes\n");
	return 0;
}

题目E 从因数中找出来两个数 (差一点就AC的)

题目描述

Recently you have received two positive integer numbers x and y. You forgot them, but you remembered a shuffled list containing all divisors of x (including 1 and x) and all divisors of y (including 1 and y). If d is a divisor of both numbers x and y at the same time, there are two occurrences of d in the list.
For example, if x=4 and y=6 then the given list can be any permutation of the list [1,2,4,1,2,3,6]. Some of the possible lists are: [1,1,2,4,6,3,2], [4,6,1,1,2,3,2] or [1,6,3,2,4,1,2].
Your problem is to restore suitable positive integer numbers x and y that would yield the same list of divisors (possibly in different order).
It is guaranteed that the answer exists, i.e. the given list of divisors corresponds to some positive integers x and y.

输入

The first line contains one integer n (2≤n≤128) — the number of divisors of x and y.
The second line of the input contains n integers d1,d2,…,dn (1≤di≤104), where di is either divisor of x or divisor of y. If a number is divisor of both numbers x and y then there are two copies of this number in the list.

输出

Print two positive integer numbers x and y — such numbers that merged list of their divisors is the permutation of the given list of integers. It is guaranteed that the answer exists.

未通过的代码
#include <stdio.h>

int main(){
	int sum;
	scanf("%d",&sum);
	int a[sum];
	int i;
	for(i=0;i<sum;i++){
		scanf("%d",&a[i]);
	}
	int max;
	int max_i;
	int max_2;
	int max_2_i;
	max=a[0];
	for(i=1;i<sum;i++){
		if(a[i]>max){
			max=a[i];
			max_i=i;
		}
	}
	a[max_i]=0;
	max_2_i=0;
	max_2=a[0];
	// max_2=a[0];
	// max_2_i=0;
	// for(i=1;i<sum;i++){
	// 	if(a[i]>max_2){
	// 		max_2=a[i];
	// 		max_2_i=i;
	// 		a[i]=0;
	// 	}
	// }
	// a[max_2_i]=0;
	for(i=1;i<sum;i++){
		if(a[i]>max_2){
			max_2=a[i];
			max_2_i=i;
		}
	}
	a[max_2_i]=0;
	while(max%max_2==0){
		max_2=a[0];
		max_2_i=0;
		for(i=0;i<sum;i++){
			if(a[i]>max_2){
				max_2=a[i];
				max_2_i=i;
		}
		a[max_2_i]=0;
	}
}
	printf("%d %d\n",max,max_2);
	return 0;
}
思路

我们可以说,最大数是一个了。其次找第二大的数。如果有两个第二大的数,那么第二大的数一定是。如果只有一个,而且第一大和第二大可以整除,那么就继续往下找。
也即:
1.最大两个数不能整除,就是他俩。
2.最大两个数可以整除,如果出现两个一样的,那么还是他。比如8 4 4 2 2 1 1,出现两个4,划掉一个4还剩一个。
3.如果还不行,继续判断。

优化代码
#include<bits/stdc++.h>
#include<map>
using namespace std;
int main(){
	int n,a[300];
	cin >> n;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+1+n);
	printf("%d ",a[n]);
	for(int i=n-1;i>=1;i--){
		if(a[n]%a[i]!=0){
			printf("%d",a[i]);
			return 0;
		}
		else if(a[i]==a[i-1] || a[i]==a[i+1]){
			printf("%d",a[i]);
			return 0;
		}
	}
}

留一个疑问,估计还是不会用sort函数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值