XJOI奋斗群 群赛2总结
A- Odds and Ends
题意
给出n个数,判断是否能分成奇数个以奇数开头结尾的子数列。
题解
因为要将其分为奇数个子序列,若n为偶数,显然无法做到,若n为奇数,判断开头结尾是否为偶数即可
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int a[100000];
for(int i=1;i<=n;i++){
cin>>a[i];
}
if(n%2==0){
cout<<"No";
}
else if(a[1]%2==0||a[n]%2==0){
cout<<"No";
}
else cout<<"Yes";
return 0;
}
B - Tell Your World
题意
给出n个坐标为(i,y[i])的点,判断是否能以两条平行线涵盖所有点。
题解
分三类情况讨论:点1,2共线;点1,2异线,1,3共线;点1,2异线,2,3共线;
若满足任意一种 输出YES,都不满足,输出NO;写法比较简单,模拟即可;注意需要特判n<=2的情况;
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int a[100000];
for(int i=1;i<=n;i++){
cin>>a[i];
}
if(n%2==0){
cout<<"No";
}
else if(a[1]%2==0||a[n]%2==0){
cout<<"No";
}
else cout<<"Yes";
return 0;
}
C - From Y to Y
题意
在一个集合中任取两个元素(每个元素也是一个集合),对于两个元素共同拥有的元素在取出的那两个元素中分别出现的次数的乘积就是花费,然后再将两个元素合并成一个元素再放进去,重复上述步骤n-1次,直到集合只有一个元素 。
题解
由于可能的解很多,所以要建立起自己的一套方法,例如集合{a,a,a,a}合并后的总代价为6,不够的话再用下一个字母去凑,最后注意特判0;
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,ans=0;
cin>>n;
if(n==0){
printf("%c",'a');
}
string s;
for(char i='a';i<='z';++i){
if(n==ans) break;
else{
for(int j=0;j+ans<=n;++j){
ans=ans+j;
s=s+i;
}
}
}
cout<<s;
}
D - Harmony Analysis
题意
建立起一个2^k的字符矩阵,由+、*两种组成,使得每两行之间有2^(k-1)个字符不同。
题解
以k=1时的矩阵作为基本图形进行递归,找到一定规律即可,重点是思路很难想到,需要特判0的情况。
#include<bits/stdc++.h>
using namespace std;
char c[1000][1000];
void f(int a,int b,int n,int d){
if(n==1){
if(d==1){
c[a][b]=c[a+1][b]=c[a][b+1]='+';
c[a+1][b+1]='*';
}
if(d==0){
c[a][b]=c[a+1][b]=c[a][b+1]='*';
c[a+1][b+1]='+';
}
}
else{
f(a,b,n-1,d);
f(a+pow(2,n-1),b,n-1,d);
f(a,b+pow(2,n-1),n-1,d);
f(a+pow(2,n-1),b+pow(2,n-1),n-1,1-d);
}
}
int main(){
int n;
cin>>n;
if(n==0){
cout<<"+";
return 0;
}
else f(1,1,n,1);
for(int i=1;i<=pow(2,n);i++){
for(int j=1;j<=pow(2,n);j++){
cout<<c[i][j];
}
cout<<endl;
}
return 0;
}
E - Bear and Prime Numbers
题意
首先输入n个数,之后给出m个范围,找出每个范围内的质数,并找出每个质数能被之前输入的数整除的个数,每个范围输出一次。
题解
写法很简单,但有很多大数据卡TLE,之前优化好几次质数的筛选都没有AC,结束后把“cin”,“cout”
改成“scanf”“printf”直接AC了2333。
#include<bits/stdc++.h>
const int N = 10000005;
int n,m,v[N]={0},g[N]={0},s[N]={0};
int main() {
int a, b;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a);
g[a]++;
}
for (int i = 2; i < N; i++) {
if (v[i]!=0) continue;
for (int j = i; j < N; j += i) {
if (g[j]!=0) s[i] += g[j];
v[j] = 1;
}
}
for (int i = 1; i < N; i++) s[i] += s[i-1];
scanf("%d", &m);
for (int i = 0; i < m; i++){
scanf("%d%d", &a, &b);
if (a >= N) a = N;
if (b >= N) b = N - 1;
printf("%d\n", s[b] - s[a-1]);
}
return 0;
}
总结
最终RANK:6
待提升:
优化代码时可以把“cin”,“cout”改成“scanf”“printf”,在其他方法行不通时可以尝试用递归。
FIGHTING!
2017年9月4日