FYN OI奋斗之路2~
来源:互联网 发布:mac上传图片 编辑:程序博客网 时间:2024/06/03 08:05
- XJOI 奋斗群 群赛3
- A - Kirill And The Game
- 题意
- 题解
- B - Gleb And Pizza
- 题意
- 题解
- C - Ilya And The Tree
- 题意
- 题解
- D - Mike and gcd problem
- 题意
- 题解
- E - Bank Hacking
- 题意
- 题解
- 总结
- 最终RANK8
- 待提升
- FIGHTING
- A - Kirill And The Game
XJOI 奋斗群 群赛3
A - Kirill And The Game
题意
输入两个区间l-r、x-y和一个数k,判断是否能在第一个区间找出一个数a,第二个区间找出一个数b,使得a除以b等于k。
题解
遍历一遍第一个区间,找出是否能使a*k在第二个区间范围内,若能,输出“Yes“,否则输出”No“。
#include<bits/stdc++.h>using namespace std;int main(){ long long int l,r,x,y,ans,k; cin>>l>>r>>x>>y>>k; for(int i=x;i<=y;i++){ ans=i*k; if(ans>=l&&ans<=r){ cout<<"YES"; return 0; } } cout<<"NO"; return 0;}
B - Gleb And Pizza
题意
输入一个大圆半径r和外环宽度d,再输入n个小圆的相关参数:圆心的坐标(x,y)和半径l。求出不在外环上的小圆个数(原题用的比萨和香肠2333)
题解
由于数据比较小,依次判断每一个小圆是否符合要求即可,需要注意外环宽度为0,小圆半径为0的情况比较特殊。
#include<bits/stdc++.h>using namespace std;int main(){ int a,b,n; int dis; int ans=0; int x[100000],y[100000],r[100000]; scanf("%d %d %d",&a,&b,&n); b=a-b; for(int i=1;i<=n;i++){ scanf("%d %d %d",&x[i],&y[i],&r[i]); dis=x[i]*x[i]+y[i]*y[i]; if(b!=0){ if(dis<=(a-r[i])*(a-r[i])&&dis>=(b+r[i])*(b+r[i])) ans++; } else{ if(r[i]==0){ if(a*a==dis) ans++; } } } cout<<ans;}
C - Ilya And The Tree
题意
有一棵树,每个结点有一权值,求对于每个结点,根节点到该结点的所有数的最大公约数(对于每一条路径,可将一个数改为0,gcd(a,0)=a。
题解
建树用set存储每一条路径的gcd值,方法很简单但不太会建树所有拖了比较久。
#include<bits/stdc++.h>using namespace std;const int MAXN=200100;int ans[MAXN]={0},first[MAXN]={0},a[MAXN]={0},t[MAXN]={0},n,cnt;bool visit[MAXN];struct edge{ int to,next;}e[MAXN];set <int> ans1[MAXN];int gcd(int a,int b){ int x; while(b!=0){ x=a; a=b; b=x%b; } return a;}void dfs(int x){ visit[x]=true; int k=first[x]; ans[x]=gcd(ans[t[x]],a[x]); ans1[x].insert(ans[t[x]]); set <int>::iterator it=ans1[t[x]].begin(); while(it!=ans1[t[x]].end()){ ans1[x].insert(gcd(*it,a[x])); it++; } while(k!=0){ if(!visit[e[k].to]){ t[e[k].to]=x; dfs(e[k].to); } k=e[k].next; }}int main(){ memset(visit,false,sizeof(visit)); int x,y,k; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<n;i++){ scanf("%d %d",&x,&y); e[++cnt].to=y; e[cnt].next=first[x]; first[x]=cnt; e[++cnt].to=x; e[cnt].next=first[y]; first[y]=cnt; } ans[1]=a[1]; ans1[1].insert(0); visit[1]=true; k=first[1]; while(k!=0){ t[e[k].to]=1; dfs(e[k].to); k=e[k].next; } set <int>::reverse_iterator it; for(int i=1;i<=n;i++){ it=ans1[i].rbegin(); printf("%d ",max(*it,ans[i])); } return 0;}
D - Mike and gcd problem
题意
输入一串n个数组成的序列,要求求出最少的操作次数使得该数列的最大公约数大于1,每一次操作可将数字a[i]、a[i+1]用a[i]-a[i+1]、a[i]+a[i+1]。若无法完成,输出”No“。
题解
先判断初始的最大公约数是否大于1,若不不大于1,则要将其变为2,将奇奇变成偶偶需要一次操作,将奇偶或偶奇变成偶偶需要两次操作。所以先处理奇奇,然后再处理其他情况。用贪心写即可。
#include<bits/stdc++.h>using namespace std;int gcd(int num1,int num2){ if(num1<0) num1=abs(num1); else if(num2<0) num2=abs(num2); int m1=max(num1,num2); int m2=min(num1,num2); if(num1==0||num2==0){ return m1; } else{ for(int i=m2;i>=1;i--){ if(num1%i==0&&num2%i==0) return i; } }}int main(){ int n,a[100001]; scanf("%d",&n); int count=0,ans=0,flag=0; int num,temp; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); if(a[i]!=0) flag=1; } if(flag==1){ for(int i=2;i<=n;i++){ if(i==2)num=gcd(a[1],a[i]); else num=gcd(num,a[i]); } if(num!=1) printf("YES\n0"); else{ for(int i=1;i<=n-1;i++){ if(a[i]%2==1&&a[i+1]%2==1){ count++; temp=a[i]; a[i]=temp-a[i+1]; a[i+1]=temp+a[i+1]; } } for(int i=1;i<=n;i++){ if(a[i]%2==0&&a[i+1]%2==1){ count=count+2; temp=a[i]; a[i]=temp-a[i+1]; a[i+1]=temp+a[i+1]; temp=a[i]; a[i]=temp-a[i+1]; a[i+1]=temp+a[i+1]; } if(a[i]%2==1&&a[i+1]%2==0){ count=count+2; temp=a[i]; a[i]=temp-a[i+1]; a[i+1]=temp+a[i+1]; temp=a[i]; a[i]=temp-a[i+1]; a[i+1]=temp+a[i+1]; } } printf("YES\n%d",count); } } else printf("NO");}
E - Bank Hacking
题意
有n个点,每个点有初始的实力,给出n-1条线使两点之间互相连接,之后攻击某一个点,第一个点只要求实力大于该点实力,攻击一个点后与改点相邻(直接相连)或半相邻(用两条线相连)的点实力会加1。第二个点需要与被攻击的点相邻。
题解
每个点的实力最多提升2次,因此只要可以分两类讨论:
1.若只有一个最大的点,只需枚举该点相邻的点即可,若所有的权值等于最大值-1的点都与该点相邻或半相邻,输出最大值即可,反之,输出最大值+1;
2.若最大的点不止一个,对于每个最大的点,枚举相邻与半相邻的点,若所有最大的点都互相相邻或半相邻,输出最大值+1,反之,输出最大值+2。
#include<bits/stdc++.h>using namespace std;const int inf=1e9+10;vector <int> a[1000000];int power[10000000],start,end;int main(){ int n,m=-inf,temp; int count1=0,count2=0; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&power[i]); m=max(m,power[i]); } for(int i=1;i<=n-1;i++){ scanf("%d %d",&start,&end); a[start].push_back(end); a[end].push_back(start); } for(int i=1;i<=n;i++){ if(power[i]==m) { count1++; temp=i; } else if(power[i]==m-1) count2++; } if(count1==1){ int cnt=0; for(int i=0;i<a[temp].size();i++){ if(power[a[temp][i]]==m-1) cnt++; } if(cnt==count2) printf("%d",m); else printf("%d",m+1); } else{ bool flag=false; for(int i=1;i<=n;i++){ int cnt=0; if(power[i]==m) cnt++; for(int j=0;j<a[i].size();j++){ if(power[a[i][j]]==m) cnt++; } if(cnt==count1) flag=true; } if(flag) printf("%d",m+1); else printf("%d",m+2); } return 0;}
总结
最终RANK:8
待提升
因数据范围问题导致的错误比较多,注意特殊情况的单独讨论。
FIGHTING!
2017年9月5日
- FYN OI奋斗之路2~
- FYN OI奋斗之路1~
- FYN OI奋斗之路3~
- FYN OI奋斗之路4~
- FYN OI奋斗之路5~
- FYN OI奋斗之路6~
- FYN OI 奋斗之路7~
- FYN OI 奋斗之路8~
- FYN OI奋斗之路9~
- FYN OI 奋斗之路10~
- FYN OI奋斗之路11~
- OI 酱油之路
- OI之路
- OI之路就此终结
- czl蒻蒟的OI之路2
- 【OI之路】01函数和STL-2STL
- 【OI之路】02数论算法-2素数判断
- 【OI之路】04排序搜索-2系统快排
- RxJAVA操作符
- python 包和模块 等于号(==)和is的区别与联系 对象的拷贝(copy)
- JQ分页
- sqlite3中,blob字段的读取和写入
- vue+vuex+localStorage实现记事本
- FYN OI奋斗之路2~
- RecyclerView嵌套CheckBox实现单选全选反选操作每条Item添加分割线
- Java中的注意事项
- C语言(26)蛇形填数2
- c++定时器SetTimer
- CentOS 7中安装指定的Kernel版本
- vue用法总结
- Mybatis入门程序
- BZOJ 2160: 拉拉队排练