奋斗群群赛—3
T1:Kirill And The Game
题目位置:
http://codeforces.com/problemset/problem/842/A
题意:
即输入 l,r,x,y 求在l~r与x~y的循环之中是否存在比值直接为k的可能,有,就输出YES,没有就输出NO.就这么简单!
AC代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long int l,r,x,y,k;
// double k;
cin>>l>>r>>x>>y>>k;
int flag=0;
for(long int j=x; j<=y; j++)
{
long long int i;
i=j*k;
if(i>r) break;
if(i<=r&&i>=l)
{
flag=1;
//return 0;
}
}
if(flag==1) cout<<"YES";
else cout<<"NO";
}
小反思:
利用一个flag来记录着可能性,但可以适当的加快程序,比如i/j==k,即求i==j*k;
但如果直接i超出了y,那么肯定不行,直接退出!
T2:Gleb And Pizza
题目位置
http://codeforces.com/problemset/problem/842/B
题意:
即求出在半径为r~d的一个圆环中,求这些小圆有没有直接在圆环之中被包围,有的话答案就加1,输出tot的可能性!
AC代码:
#include <bits/stdc++.h>
using namespace std;
int r,d;
int n,tot=0;
bool judge(int x,int y,int l)
{
double dis;
dis=sqrt(x*x+y*y);
if(dis-(double)l>=(double)(r-d)&&dis+(double)l<=r)
return true;
return false;
}
int main()
{
int x,y,l;
cin>>r>>d>>n;
for(int i=1; i<=n; i++)
{
cin>>x>>y>>l;
if(judge(x,y,l)==true) tot++;
}
cout<<tot;
}
小反思:
直接利用两点间线段最短的问题,创造了一个函数来对其进行求解就好啦,不超出自己的r的位置就好!
T3:Gleb And Pizza
题目位置:
http://codeforces.com/problemset/problem/842/B
题意:
一棵根节点为 1 的树,每个节点都有权值,求从根节点到每个点路径所有权值的最大 gcd 。(我们可以把每条路径上一个点的权值变为 0 )
AC代码:
暂无…
T4:Mike and gcd problem
题目位置:
http://codeforces.com/problemset/problem/798/C
题意:
知道是mike有一段长度为n的int 数据,对于ai和ai+1,可以进行将2个数变成ai-ai+1与ai+ai+1的操作,问题是是否能找到多少次操作,使其的n个数的gcd不为1.如果有,输出YES并加上操作次数,没有就输出NO!
AC代码
#include<bits/stdc++.h>
using namespace std;
long long int a[200005],book[200005];
long long int gcd(long long int x,long long int y)
{
if(y==0) return x;
return gcd(y,x%y);
}
int main()
{
long long int n,tot=0;
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>a[i];
if(a[i]%2==0)
book[i]=1;
}
long long int d=gcd(a[1],a[2]);
for(int i=3; i<=n; i++)
{
d=gcd(d,a[i]);
}
if(d!=1)
{
cout<<"YES"<<endl<<0;
return 0;
}
for(int i=1; i<=n-1; i++)
{
if(book[i]==0&&book[i+1]==0) //情况为 奇数 &奇数
{
book[i]=1;
book[i+1]=1;
tot++;
}
}
for(int i=1; i<=n-1; i++)
{
if((book[i]==0&&book[i+1]==1)||(book[i]==1&&book[i+1]==0)) //情况为 奇数 &偶数
{
book[i]=1;
book[i+1]=1;
tot+=2;
}
}
cout<<"YES"<<endl;
cout<<tot<<endl;
}
小总结:
1.要想到算最开始的gcd,防止漏判
2.这些i-(i+1)与i+(i+1)的点就是使其变为偶数与偶数,奇数与奇数操作一次,奇数与偶数操作2次就好,但记住要放在2个循环中,一个是判断奇数与奇数的情况,一个是奇数与偶数,偶数与奇数的情况,不能够一起判,比如1,3,5,7 四个奇数,只要4此操作,但是如果2个循环一起判断就是好像是5次吧!反正不对就是了!所以要注意!
T5: Bank Hacking
题目位置:
http://codeforces.com/problemset/problem/796/C
题意:
就是说一只狗狗要”抢劫”银行,有银行n个第一次输入的是ai的银行的防御值,在接下来的n-1行之中,会有x,y 2个数,表示x与y是连接的,而连接的连接就是半连接的。而每次劫一个银行,与其相连和半连接的就是+1.求电脑的攻击力的最小值!
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int N=6000005;
int a[N],point[N],first[N],next[N];
int E;
void add(int a,int b)
{
point[E]=b;
next[E]=first[a]; //???first?i? ?????????,?next??
first[a]=E; //?????first?a??? E ?? ??????next[]??E
E++; //????? ++ ??
}
int main()
{
int n,maxn=-1000005000;
scanf("%d",&n);
memset(first,-1,sizeof(first));
memset(next,-1,sizeof(next));
int mx=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
if(a[i]==maxn) mx++;
if(a[i]>maxn)
{
maxn=a[i];
mx=1;
}
}
int mc=0,E=0;
for(int i=1; i<=n; i++)
if(a[i]==maxn-1) mc++;
for(int i=1; i<n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
//ÕÒ³öiµãÁ¬µÄ×îºóÒ»µãµÄ±ßµÄ±àºÅ first[i] ,Ö®ºóÔÙ´ænextÊý×éÖ®ÖÐ
// Á¬½ÓµÄµãµÄÖµÔÚpoint[]Êý×éÖ®ÖÐ
if(mx==1)
{
int k;
for(int i=1; i<=n; i++)
if(a[i]==maxn)
{
k=i;
break;
}
k=first[k];
//cout<< k<<"no.1"<<endl;
int tot=0;
while(k!=-1)
{
//cout<<a[point[k]]<<endl;
if(a[point[k]]==maxn-1)
tot++;
k=next[k];
}
if(tot==mc)
{
cout<<maxn;
return 0;
}
else
{ //cout<<tot<<endl;
cout<<maxn+1;
return 0;
}
}
else
{
int flag=0;
for(int i=1; i<=n; i++)
{
int count=0;
if(a[i]==maxn)count++;
int k=first[i];
while(k!=-1)
{
if(a[point[k]]==maxn)
count++;
k=next[k];
}
if(count==mx) flag=1;
}
if(flag==1)
{
cout<<maxn+1;
return 0;
}
else cout<<maxn+2;
}
}
小总结:
总体想法:
设定maxn==max(a【i】)【1<=i<=n】,mx表示maxn的个数,mc表示maxn-1的个数。
①ans==maxn. 当且仅当mx==1.并且这个点的周围的maxn-1的个数==mc.
②ans==maxn+1.如果mx==1.并且这个点的周围的maxn-1的个数
总结
今天还算不错,但是面对错了的题目,要抱着错100遍的心态;
对于排名,要做到“粪土当年万户侯”的心态,加油吧!
1.找规律,对于题目要尽量想到简便的方法来解决它,减少次数
2.做到巧妙的转换数据类型,如果数据类型要求苛刻的题就要更仔细一些!
3.考虑到搜索的算法,对于树的问题要想清楚
4.理由数论来解决问题!想清楚!