T1 Kirill And The Game
题意:
输入a,b,c,d,e五个数,问ab范围内的整数f与cd范围内的整数g的商能否等于e.
解法:
暴力模拟。
代码:
#include<bits/stdc++.h>
using namespace std ;
int main()
{
double L,R,X,Y,K,m;
int a=0 ;
cin >>L>>R>>X>>Y>>K;
for (long long i=X; i<=Y; i++)
{
m=i*K;
if (m>=L&&m<=R)
{
cout <<"YES" ;
return 0 ;
}
}
cout <<"No" ;
return 0 ;
}
小结:
**此类题目不要多想。**
T2 Gleb And Pizza
题意:
题目大意:以原点为圆心有一个大圆,半径为r,现在给你几个圆和半径,现在问你有几个小圆完整的存在与r-d这个区间内.
解法:
模拟暴力.
代码:
#include<bits/stdc++.h>
using namespace std ;
int x[4 ];
int main()
{double xj;
int a,b,c,d=0 ;
cin >>a>>b>>c;
b=a-b;
for (int i=1 ;i<=c;i++)
{
cin >>x[1 ]>>x[2 ]>>x[3 ];
xj=sqrt (x[1 ]*x[1 ]*1.0 +x[2 ]*x[2 ]*1.0 );
if (b+x[3 ]<=xj*1.0 &&xj+x[3 ]<=a)
d++;
}
cout <<d;
return 0 ;
}
小结:
**此类题目看图重要。**
T3 Ilya And The Tree
题意:
给一棵树,从每个点到根,你可以把路上的某一个点变成0,问最大公因数是多少。
解法:
结构体。
代码:
#include <bits/stdc++.h>
using namespace std ;
const int maxn = 2e5 ;
int n, A[maxn + 10 ], dp[maxn + 10 ][2 ], fa[maxn + 10 ];
vector <int > g[maxn + 10 ];
set <int > s[maxn + 10 ];
void dfs(int v, int p, int b)
{
for (int w : s[p])
s[v].insert(__gcd(w, A[v]));
s[v].insert(b);
b = __gcd(b, A[v]);
s[v].insert(b);
for (int w : g[v])
if (w != p)
dfs(w, v, b);
}
int main()
{
scanf ("%d" , &n);
for (int i = 1 ; i <= n; i++)
scanf ("%d" , A + i);
int u, v;
for (int i = 1 ; i < n; i++)
{
scanf ("%d%d" , &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1 , 0 , 0 );
for (int i = 1 ; i <= n; i++)
printf ("%d " , *s[i].rbegin());
return 0 ;
}
}
小结:
**此类题目需要特判。**
T4 Mike and gcd problem
题意:
输入一个数字a,用特定的方法输出一串字符,使他的价值为a.(具体详见原题)
解法:
近似分型.
代码:
#include<bits/stdc++.h>
using namespace std ;
char x[1000 ][1000 ];
int main() {
int a,b=2 ;
x[1 ][1 ]='+' ;
x[1 ][2 ]='+' ;
x[2 ][1 ]='+' ;
x[2 ][2 ]='*' ;
cin >>a;
if (a==0 )
{cout <<"+" ;
return 0 ;
}
while (a!=1 ) {
for (int i=1 ; i<=b; i++)
for (int j=1 ; j<=b; j++) {
x[i+b][j]=x[i][j];
x[i][j+b]=x[i][j];
if (x[i][j]=='+' )
x[i+b][j+b]='*' ;
else
x[i+b][j+b]='+' ;
}
b=b*2 ;
a--;
}
for (int i=1 ;i<=b;i++)
{
for (int j=1 ;j<=b;j++)
cout <<x[i][j];
cout <<endl;
}
return 0 ;
}
小结:
**此类题目可以先手算找规律。**
T5 Bank Hacking
题意:
每hack一个银行,与其相连的或者半相连的银行的强度都要加1,与其相邻就是两者之间有边,如果i和k是半相邻,那么i与j之间有边,j与k之间有边(如果j银行被hack了,那么i和k就不是半相邻关系了)。
解法:
邻接表
代码:
using namespace std;
struct Line {
int point,next ;
} line[N*2 +7 ];
int head[N+7 ],e,n,i,j,x ,y ,t[N+7 ],ans,maxn=-inf,ma ,mc,ma _ ,mc_ ;
void add(int a,int b) {
line[e].point=b;
line[e].next =head[a];
head[a]=e;
e++;
}
int main() {
for (scanf("%d " ,&n),i=1 ; i<=n; i++) scanf("%d " ,&t[i]),maxn=max(maxn,t[i]);
memset(head,-1 ,sizeof(head));
ans=maxn+3 ;
for (i=0 ; i<n-1 ; i++) {
scanf("%d %d " ,&x ,&y );
add(x ,y );
add(y ,x );
}
for (i=1 ; i<=n; i++) {
if (t[i]==maxn) ma ++,t[i]=2 ;
else if (t[i]==maxn-1 ) mc++,t[i]=1 ;
else t[i]=0 ;
}
for (i=1 ; i<=n; i++) {
if (t[i]==2 ) {
ma _ =0 ;
mc_ =0 ;
for (j=head[i]; j!=-1 ; j=line[j].next ) {
if (t[line[j].point]==1 ) mc_ ++;
else if (t[line[j].point]==2 ) ma _ ++;
}
if (ma -ma _ -1 ) ans=min(ans,maxn+2 );
else {
if (ma _ ||mc-mc_ ) ans=min(ans,maxn+1 );
else
ans=min(ans,maxn);
}
} else {
ma _ =0 ;
for (j=head[i]; j!=-1 ; j=line[j].next ) {
if (t[line[j].point]==2 ) ma _ ++;
}
printf ("\n\n" );
if (ma _ ==ma ) ans=min(ans,maxn+1 );
}
}
printf ("%d " ,ans);
return 0 ;
}
小结:
**急需特判**