1. 程式人生 > >Noip 2017 最簡單的三道題

Noip 2017 最簡單的三道題

A了這三道題,就可以穩拿一D了(山東)
Day1 T1
雖說是個數論題,打表出結論!

#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
int main()
{
    freopen("math.in","r",stdin);
    freopen("math.out","w",stdout);
    ll a,b;
    scanf("%lld%lld",&a,&b);
    if(a<b) swap(a,b);
    printf
("%lld",a*(b-1)-b); return 0; }

Day1 T2
很明顯的是一個棧模擬,但需要很多特判,很考驗程式碼能力。
考場上的程式碼很醜!

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
bool vis[200];
char s1[20000];
struct node{
    int z;
    bool ok;
    bool f;
}s[1000];
int top;
int
check() { bool ok=1; int maxi=0; for(int i=1;i<=top;i++) { if(ok==1&&s[i].f==1) maxi++; if(s[i].ok==0) ok=0; } return maxi; } void get_ans() { memset(vis,0,sizeof(vis)); top=0; int maxi=0; int flag1=0; bool f=0; int n,time=0; scanf
("%d ",&n); //if(n%2) flag1=1; gets(s1); int len=strlen(s1); for(int i=0;i<len;i++) { if(s1[i]=='n') f=1; if(s1[i]>='0'&&s1[i]<='9'&&f) time=time*10+s1[i]-'0'; } if(time==0) f=0; bool ok=1; for(int i=1;i<=n;i++) { gets(s1); int len=strlen(s1); if(flag1) continue; if(s1[0]=='E') { if(top==0) { flag1=1; continue; } maxi=max(maxi,check()); vis[s[top--].z]=0; continue; } top++; if(vis[s1[2]-'a'+1]) { flag1=1; continue; } vis[s1[2]-'a'+1]=1; s[top].z=s1[2]-'a'+1; int f1=0,f2=0; bool o1=0; for(int j=4;j<len;j++) { if(s1[j]=='n') { if(f1==0) f1=200; else f2=200; } if(s1[j]>='0'&&s1[j]<='9') { if(o1==0) f1=f1*10+s1[j]-'0'; else f2=f2*10+s1[j]-'0'; } if(s1[j]==' ') o1=1; } if(f1==200&&f2==200) { s[top].ok=1; s[top].f=0; continue; } else { if(f1<=100&&f2==200) { s[top].ok=1; s[top].f=1; continue; } else { if(f1>f2) s[top].ok=0,s[top].f=0; else s[top].ok=1,s[top].f=0; } } } if(flag1||top!=0) printf("ERR\n"); else { if(time!=maxi) printf("No\n"); else printf("Yes\n"); } //printf("%d %d",f,time); } int main() { //freopen("complexity.in","r",stdin); //freopen("complexity.out","w",stdout); int t; scanf("%d\n",&t); while(t--) get_ans(); return 0; }

Day2 T1
建圖+DFS 沒有並查集快!

#include <cstdio>
#include <iostream>
#include <set>
#include <queue>
#include <cmath>
#include <cstring>
#define ll long long
using namespace std;
const int maxm=1010*1010;
struct node{
    ll x,y,z;
}a[maxm];
int head[1010],net[2*maxm],to[2*maxm];
int cnt;
bool vis[1011];
ll jx=2;
ll get(ll a1,ll a2)
{
    ll ans=(a[a1].x-a[a2].x)*(a[a1].x-a[a2].x)+(a[a1].y-a[a2].y)*(a[a1].y-a[a2].y)+(a[a1].z-a[a2].z)*(a[a1].z-a[a2].z);
    return ans;
}
void add(int x,int y)
{
    cnt++;
    to[cnt]=y;
    net[cnt]=head[x];
    head[x]=cnt;
}
ll read()
{
    ll x=0,w=1;
    char s=0;
    while(s<'0'||s>'9') 
    {
        if(s=='-') w=-1;
        s=getchar();
    }
    while(s>='0'&&s<='9')
    {
        x=(x<<3)+(x<<1)+s-'0';
        s=getchar();
    }
    return x*w;
}
bool dfs(int x,int e)
{
    //vis[x]=1;
    if(x==e)
     return 1;
    for(int i=head[x];i;i=net[i])
    {
        int p=to[i];
        if(vis[p]) continue;
        vis[p]=1;
        bool d=dfs(p,e);
        if(d) return 1;
    }
    return 0;
}
void work()
{
    memset(a,0,sizeof(a));
    memset(head,0,sizeof(head));
    memset(net,0,sizeof(net));
    memset(to,0,sizeof(to));
    memset(vis,0,sizeof(vis));
    int flag1=1,flag2=1;
    cnt=0;
    int n;
    ll h,r;
    scanf("%d%lld%lld",&n,&h,&r);
    for(int i=1;i<=n;i++)
     a[i].x=read(),a[i].y=read(),a[i].z=read();
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
         if((jx*r*jx*r)>=get(i,j)) add(i+1,j+1),add(j+1,i+1);
        if(a[i].z-r<=0) add(1,i+1),add(i+1,1),flag1=0;
        if(a[i].z+r>=h) add(i+1,n+2),add(n+2,i+1),flag2=0;
    }
    if(flag1||flag2) 
    {
        printf("No\n");
        return;
    }
    //printf("%d %d\n",flag1,flag2);
    vis[1]=1;
    bool f=dfs(1,n+2);

    if(f) printf("Yes\n");
    else printf("No\n");

    return;
}
int main()
{
    //freopen("cheese.in","r",stdin);
    //freopen("cheese.out","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
     work();
    return 0;
}