HZNU Training 6 for Zhejiang Provincial Competition 2020

Solve A B C D E F G H I J K
7/11 Ø Ø    


 

A - A

 CodeForces - 1097B 

 签到,判断是否360倍数,dfs解决;

#include<bits/stdc++.h>
using namespace std;
bool flag;
int a[100];
    int n;
void dfs(int pass,int sum){
    if((sum%360==0)&&pass==n){flag=1;return ;}
    
    if(flag||pass==n)return ;
    dfs(pass+1,sum+a[pass+1]);
    dfs(pass+1,sum-a[pass+1]);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    flag=0;
    dfs(1,a[1]);
    if(flag)puts("YES");
    else puts("NO");
    // system("pause");
    return 0;
}
View Code

B - B

 CodeForces - 1144F 

裸的二分图染色,dfs解决,bfs不可;

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=2e5+5;
struct edge{int u,v;edge(int a,int b){u=a,v=b;}};
vector<int>e[N];
vector<edge>t;
int color[N];
bool flag;
void dfs(int u,int pass){
    color[u]=pass;
    if(!flag)return ;
    for(int i=0;i<e[u].size();i++){
    int v=e[u][i];
    if(color[v]<0)dfs(v,1-pass);
    if(color[v]==color[u]){flag=0;return ;}
    }
}
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)color[i]=-1;
    while(m--){
    int u,v;
    scanf("%d %d",&u,&v);
    e[u].pb(v);e[v].pb(u);
    t.pb(edge(u,v));
    }
    flag=1;
    dfs(1,1);
    if(!flag){puts("NO");return 0;}
    puts("YES");
    string s;
    for(int i=0;i<t.size();i++){
    if(color[t[i].u]==1)s+='1';
    else s+='0';
    }
    cout<<s<<endl;
    // system("pause");
    return 0;
}
View Code

C - C

 CodeForces - 1110E 

留坑

题意:看完题解我笑了,不知如何说起;

有如下规律

 

 

a[i-1] a[i] a[i+1]
差分: a[i]-a[i-1] a[i+1]-a[i]
变换后:a[i-1] a[i-1]+a[i+1]-a[i] a[i+1]
差分:a[i+1]-a[i] a[i]-a[i-1]
意思就是变换后的差分序列只是变了顺序;
枚举c数组和t数组的差分,然后特判一下;

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
const int N=1e5+5;
int c[N],t[N],dc[N],dt[N];
int main(){
   int n;
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    for(int i=1;i<=n;i++)scanf("%d",&t[i]);
    for(int i=2;i<=n;i++)dc[i]=c[i]-c[i-1];
    for(int i=2;i<=n;i++)dt[i]=t[i]-t[i-1];
    sort(dc+2,dc+1+n);
    sort(dt+2,dt+1+n);
    if(c[1]!=t[1]||t[n]!=t[n]){puts("No");return 0;};
    for(int i=2;i<=n;i++){
    if(dc[i]!=dt[i]){puts("No");return 0;}
    }
    puts("Yes");
    return 0;
}
View Code

 

 

D - D

 CodeForces - 659D 

两种解法;

解法1:一一枚举;四种情况;

#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define pb push_back
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=1e5+5;
struct point{int x, y;}P[N];
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d %d",&P[i].x,&P[i].y);
    int ans=0;
    for(int i=2;i<n;i++){
    if(P[i].y==P[i-1].y&&P[i].x>P[i-1].x&&P[i+1].x==P[i].x&&P[i+1].y>P[i].y)ans++;
    else if(P[i].x==P[i-1].x&&P[i].y>P[i-1].y&&P[i].y==P[i+1].y&&P[i].x>P[i+1].x)ans++;
    else if(P[i].y==P[i-1].y&&P[i].x<P[i-1].x&&P[i+1].x==P[i].x&&P[i].y>P[i+1].y)ans++;
    else if(P[i].x==P[i-1].x&&P[i].y<P[i-1].y&&P[i].y==P[i+1].y&&P[i].x<P[i+1].x)ans++;
    }
    printf("%d\n",ans);
    // system("pause");
    return 0;
}
View Code

 

 

 

 

 解法二:观察上面图像,b必在a的逆时针方向,叉积判断即可;

 

#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i++)
#define pb push_back
using namespace std;
typedef long long ll;
const int N=1e3+5;
const double eps=1e-8;
// struct Point{int x,y;}P[N];
struct point{
    int x,y;
    point(){}
    point(int a,int b):x(a),y(b){}
    // point(int a,int b){x=a,y=b;}
}P[N];
point Vector(point a,point b){return point(b.x-a.x,b.y-a.y);}
// int dot(point a,point b){}
int main(){
    int n;
    scanf("%d",&n);
    int ans=0;
    for(int i=1;i<=n;i++)scanf("%d %d",&P[i].x,&P[i].y);
    for(int i=2;i<n;i++){
    point a=Vector(P[i-1],P[i]);
    point b=Vector(P[i],P[i+1]);
    if((a.x*b.y-a.y*b.x)>0)ans++;
    }
    cout<<ans<<endl;
    // system("pause");
    return 0;
}
View Code

E - E

 ZOJ - 2972 

dp,有点类似背包;

每一步可以中速,高速,慢速,

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=2e2+15;
int t1[N],t2[N],t3[N],f1[N],f2[N];
int dp[N][N];
int main(){
    int t,n,m;
    scanf("%d",&t);
    while(t--){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    scanf("%d %d %d %d %d",&t1[i],&t2[i],&t3[i],&f1[i],&f2[i]);
    memset(dp,inf,sizeof dp);
    dp[0][m]=0;
    for(int i=1;i<=n;i++)
    for(int j=0;j<=m;j++){
    if(j>=f1[i]&&dp[i][j-f1[i]]>dp[i-1][j]+t1[i])
    dp[i][j-f1[i]]=dp[i-1][j]+t1[i];
    if(dp[i][j]>dp[i-1][j]+t2[i])
    dp[i][j]=dp[i-1][j]+t2[i];
    if(j+f2[i]<=m&&dp[i][j+f2[i]]>dp[i-1][j]+t3[i])
    dp[i][j+f2[i]]=dp[i-1][j]+t3[i];
    if(j+f2[i]>=m&&dp[i][m]>dp[i-1][j]+t3[i])
    dp[i][m]=dp[i-1][j]+t3[i];
    }
    int ans=inf;
    for(int j=0;j<=m;j++)
    ans=min(ans,dp[n][j]);
    printf("%d\n",ans);
    
    }
    // system("pause");
    return 0;
}
View Code

 题意:求n个数里每次选一个数异或,值最大;

字典树解决;

其实和字符串一样,能优化是因为只有01情况,高位枚举;

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e5+15;
typedef long long ll;
ll trie[32*N][2];
int  val[N*32];
int tot;
void insert(ll x){
    int u=0;
    for(int i=32;i>=0;i--){
    int id=(x>>i)&1;
    if(!trie[u][id])trie[u][id]=++tot;
    u=trie[u][id];
    }
    val[u]=x;
}
int query(ll x){
    int u=0;
    for(int i=32;i>=0;i--){
    int id=(x>>i)&1;
    if(trie[u][id^1])u=trie[u][id^1];
    else u=trie[u][id];
    }
    return val[u];
}   
int main(){
    int t,n,m,cas=0;
    scanf("%d",&t);
    while(t--){
    memset(trie,0,sizeof trie);
    // memset(val,0,sizeof val);
    tot=0;
    scanf("%d %d",&n,&m);
    ll x;
    for(int i=1;i<=n;i++){scanf("%lld",&x);insert(x);};
    printf("Case #%d:\n",++cas);
    while(m--){
    scanf("%lld",&x);
    printf("%lld\n",query(x));
    }
    
    }
    // system("pause");
    return 0;
}
View Code

 水

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
#define pb push_back
#define se second
#define fi first
const int N=1e4+5;
int a[N];
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
    int n;
    scanf("%d",&n);
    map<int,int>mp;
    set<int>st;
    for(int i=1;i<=4*n;i++)scanf("%d",&a[i]),st.insert(a[i]),mp[a[i]]++;
    sort(a+1,a+1+4*n);
    int flag=1;
    for(int i=1;i<=4*n;i++)if(mp[a[i]]&1){flag=0;break;}
    if(!flag){puts("NO");continue;}
    // vector<int>
    vector<int>v;
    map<int,int>::iterator it;
    for(it=mp.begin();it!=mp.end();it++){
    for(int i=1;i<=( (it->se)/2 );i++)v.pb( it->fi );
    }
    sort(v.begin(),v.end());
    int sz=v.size();
    if(sz&1){puts("NO");continue;}
    int sum=v[0]*v[sz-1];
    for(int i=1;i<(sz/2);i++){
    if(v[i]*v[sz-i-1]!=sum){flag=0;break;}
    }
    if(!flag){puts("NO");continue;}
    else puts("YES");
    }
    // system("pause");
    return 0;
}
View Code

 

I - I

 POJ - 1703 

签到;

#include<cstdio>
using namespace std;
const int maxn=1e6+5;
int fa[maxn];
int find(int x){
    if(x==fa[x])return x;
    else 
    return fa[x]=find(fa[x]);
//    return fa[x]==x?x:find(fa[x]);
}
void build(int x,int y){
    int dx=find(x);
    int dy=find(y);
    fa[dx]=dy;
}
int main(){
    int t,n,m;
    scanf("%d",&t);
    while(t--){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=2*n;i++)fa[i]=i;
    char op;
    int x,y;
    while(m--){
        getchar();
    scanf("%c%d%d",&op,&x,&y);
    if(op=='D'){
    build(x,y+n);
    build(x+n,y);
    }
    else {
    if(find(x)==find(y+n))
    printf("In different gangs.\n");
    else if(find(x)==find(y))
    printf("In the same gang.\n");
    else 
    printf("Not sure yet.\n");
    }
            }
    }
    return 0;
}
View Code

 

 留坑

 

 

 

 

posted @ 2020-03-12 00:13  无声-黑白  阅读(97)  评论(0)    收藏  举报