真题演练1

ACM-ICPC 2017 Asia Shenyan

F. Heron and His Triangle

三边长给出,海伦公式算出面积,暴力枚举整数情况,得:

4,14,52,194,724等数据

之后就要灵性找规律了,得:a[i] = a[i-1]*4-a[i-2]

总结:1.对于类似题目,暴力枚举出一大串数据之后,应该第一时间反应过来找规律。 2.大数题应考虑java或python写(java暂时不会)

a={}
a[1]=4
a[2]=14
for i in range(3,61,1):
    a[i]=a[i-1]*4-a[i-2]
t=int(input())
for i in range(1,t+1,1):
    k=int(input())
    for j in range(1,61,1):
        if a[j]>=k :
            print(a[j])
            print("\n")
            break
View Code

G. Infinite Fraction Path

bfs+剪枝即可

总结:对于普通情况而言,一个不起眼的剪枝根本起不到作用,但是对于十分极端情况而言,比如数据全都是同一个数,这个剪枝算是能够“特判”掉这种数据,避免超时。

#include <bits/stdc++.h>
#define debug freopen("r.txt","r",stdin)
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = 250010;
const int INF = 0x3f3f3f3f; 
const int mod = 998244353;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
struct node
{
    int step;
    ll pos;
};
int b[maxn],vis[maxn],c[maxn],i,j,t,maxx,cnt,x;
ll n;
char ans[maxn],s[maxn],a[maxn];
queue<node> q;
map <int,int> mapp;
void bfs()
{
    node k;
    while (!q.empty())
    {
        k=q.front();
        q.pop();
        if (k.step==n) continue;
        if (s[k.pos]==ans[k.step])
        {
            if (vis[k.pos]==k.step) continue;//important
            vis[k.pos]=k.step;
            k.pos=(k.pos*k.pos+1)%n;
            k.step++;
            if (s[k.pos]>=ans[k.step])
            {
                ans[k.step]=s[k.pos];
                q.push(k);
            }
        }
    }
}
int main()
{
    t=read();
    while (t--)
    {
        n=read();
        scanf("%s",s);
        maxx=-INF;
        memset(ans,-1,sizeof(ans));
        while (!q.empty()) q.pop();
        for (i=0;i<n;i++) 
        {
            maxx=max(maxx,(int)s[i]);
        }
        for (i=0;i<n;i++) 
            if (maxx==s[i])
            {
                q.push({1,i});
            }
        memset(vis,-1,sizeof(vis));
        ans[1]=maxx;
        bfs();
        printf("Case #%d: ",++cnt);
        ans[n+1]='\0';
        printf("%s",ans+1);
        printf("\n");
    }
    return 0;
}
View Code

I. Little Boxes

如果直接四个数相加,数据可能会刚好等于2^64次方,超过ull,这时候可以特判,也可以python做

总结:对于一道真的裸的不能再裸的签到题,写完应该看一眼提交榜单,或许有其他倒霉蛋踩了坑,提交上去怒收WA,这时候应该注意此题有坑。

K. Rabbits

普通签到题,没有I题裸

#include <bits/stdc++.h>
#define debug freopen("r.txt","r",stdin)
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = 150005;
const int INF = 0x3f3f3f3f; 
const int mod = 998244353;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int t,n,i,sum,a[maxn];
int main()
{
    t=read();
    while (t--)
    {
        n=read();
        sum=0;
        for (i=1;i<=n;i++) a[i]=read();
        if (a[2]-a[1]<a[n]-a[n-1])
        for (i=2;i<n;i++) sum+=a[i+1]-a[i]-1;
        else for (i=1;i<n-1;i++) sum+=a[i+1]-a[i]-1;
        cout<<sum<<endl;
    }
    return 0;
}
View Code

L. Tree

题意:给了一个无向图,题目保证了是连通图,可以看成一棵树。然后给N个结点分别涂上K种颜色,所有相同颜色的结点连在一起构成一个边集,问所有边集的交集最大是多少?

可以对边进行考虑,边连结两侧,那么只有当两侧的结点数量>=k时才可能满足该边是所有边集的公共边。统计一下满足这种条件这种公共边的数量就是答案了。

#include <bits/stdc++.h>
#define debug freopen("r.txt","r",stdin)
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = 250010;
const int INF = 0x3f3f3f3f; 
const int mod = 998244353;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int t,n,m,i,x,y,ans,son[maxn];
vector <int> G[maxn];
void dfs(int u,int father)
{
    son[u]+=1;
    for (auto v:G[u])
    {
        if (v==father) continue;
        dfs(v,u);
        son[u]+=son[v];
        if (son[v]>=m&&n-son[v]>=m) ans++;
    }
}
int main()
{
    t=read();
    while (t--)
    {
        n=read(),m=read();
        fill(son+1,son+1+n,0);
        for (i=1;i<n;i++) 
        {
            x=read(),y=read();
            G[x].push_back(y);
            G[y].push_back(x);
        }
        ans=0;
        dfs(1,0);
        cout<<ans<<endl;
        for (i=1;i<=n;i++)  G[i].clear();
    }
    return 0;
}
View Code

总结:这种题目偏长,题意也难懂但是解法相对简单的题目,需要比较深的英语、语文功底才能做的了,但是这种题目如果率先读完了解题意并且AC,或许是与别人拉开差距的题目。

猜你喜欢

转载自www.cnblogs.com/Y-Knightqin/p/12695109.html