2020 寒假 Day3

icpc上海-M-Gitignore

更简单的做法是:记录m个要保留的路径,把每个子路径都标记不能删除,然后暴力枚举n个字符串的路径,如果一个必须要删除的文件的子路径没有被标记,那么直接删除这个文件的当前子路径即可。

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef long long ll;
const int N=1e5+500;
map<string,int>mp;
string s[200];
int main(){
  int t;cin>>t;

  while(t--){
    mp.clear();
    int n,m;cin>>n>>m;
    for(int i=1;i<=n+m;i++)cin>>s[i];

    for(int i=n+1;i<=n+m;i++){
      string ss="";
      
      for(int j=0;j<s[i].size();j++){
        ss+=s[i][j];
        if(s[i][j]=='/')mp[ss]=1;
      } 
         
    }

    int ans=n;

    for(int i=1;i<=n;i++){
      string ss="";
      for(int j=0;j<s[i].size();j++){
        ss+=s[i][j];
        if(s[i][j]=='/'){
          if(mp[ss]==0)mp[ss]=2;
          else if(mp[ss]==1)continue;
          else {ans--;break;}
        }
      }

    }

    cout<<ans<<endl;



  }

 // system("pause");
  return 0;
}
View Code

B - Repository

 HDU - 2846 

模拟搜索过程,对每个字符串的后缀都建立一颗字典树,用一个belong数组标记同一个字符串的前缀,当belong发生变化时更新cnt数组, 那么查询时直接输出即可。

但数组要开到5e5左右。

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+500;
int trie[N][30];
int tot;
int belong[N],cnt[N];

void insert(char s[],int x){
    int len=strlen(s);
    int p=0;
    for(int i=0;i<len;i++){
        int n=s[i]-'a';
        if(trie[p][n]==0)trie[p][n]=++tot;
        p=trie[p][n];
        if(belong[p]!=x)cnt[p]++;
        belong[p]=x;
    }


}

int find(char s[]){
    int len=strlen(s);
    int p=0;
    for(int i=0;i<len;i++){
        int n=s[i]-'a';
        if(trie[p][n]==0)return 0;
        p=trie[p][n];
    }
    return cnt[p];
}

int main(){
    int p;cin>>p;
    tot=0;
    memset(belong,0,sizeof belong);
    memset(trie,0,sizeof trie);
    memset(cnt,0,sizeof cnt);
    getchar();
    for(int i=1;i<=p;i++){
        char s[30];
        scanf("%s",s);
        int len=strlen(s);
        for(int j=0;j<len;j++){
        insert(s+j,i);            
        }
    }
    int q;cin>>q;
    while(q--){
        char s[30];scanf("%s",s);
        // cout<<"test : ";
        printf("%d
",find(s));
    }


    // system("pause");
    return 0;

}
View Code

A - T-shirt buying

 CodeForces - 799B 

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+500;
typedef long long ll;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
int a[N],b[N],p[N];
struct node{
    int id,p;
    friend bool operator<(node a,node b){
        return a.p>b.p;
    }
};
// priority_queue<node>Q[3];
set<node>st[4];
int main(){

    int n;cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",&p[i]);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),st[a[i]].insert(node{i,p[i]});
    for(int i=1;i<=n;i++)scanf("%d",&b[i]),st[b[i]].insert(node{i,p[i]});
    
    int m;cin>>m;
    while(m--){
        int x;scanf("%d",&x);
        if(st[x].empty())cout<<-1<<" ";
        else {
            int u=st[x].rbegin()->id;
            node tmp;tmp.id=u;tmp.p=p[u];
            st[x].erase(tmp);
            cout<<p[u]<<" ";
            if(x!=1&&st[1].find(tmp)!=st[1].end())st[1].erase(tmp);
            if(x!=2&&st[2].find(tmp)!=st[2].end())st[2].erase(tmp);
            if(x!=3&&st[3].find(tmp)!=st[3].end())st[3].erase(tmp);

        }
    }

    // system("pause");~   
    return 0;

}
View Code

C - Oil Skimming

 HDU - 4185 

把每一个格子抽出来,直接二分图匹配。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=700;
vector<int>G[N];
int n;
char s[700][700];
int Hash[700][700];
int vis[N],match[N];
int tot=0;
void add(int u,int v){
  G[u].push_back(v);
  G[v].push_back(u);
}
bool findpath(int u){
  for(int i=0;i<G[u].size();i++){
    int v=G[u][i];
    if(!vis[v]){
      vis[v]=1;
      if(!match[v]||findpath(match[v])){
        match[v]=u;
        return true;
      }
    }
  }

  return false;
}
int main(){
  int t;cin>>t;
  int kase=0;
  while(t--){
    memset(G,0,sizeof G);
    memset(match,0,sizeof match);
    memset(Hash,0,sizeof Hash);
    cin>>n;
    tot=0;
    for(int i=1;i<=n;i++){
      getchar();
      for(int j=1;j<=n;j++){
        scanf("%c",&s[i][j]);
        if(s[i][j]=='#'){
          Hash[i][j]=++tot;
        }
      }
    }

    for(int i=1;i<=n;i++){
      for(int j=1;j<=n;j++){
        if(s[i][j]=='#'){
          
          if(i+1<=n&&s[i+1][j]=='#'){
            add(Hash[i][j],Hash[i+1][j]);
          }
          if(j+1<=n&&s[i][j+1]=='#'){
            add(Hash[i][j],Hash[i][j+1]);
          }

        }
      }
    }

    int ans=0;
    for(int i=1;i<=tot;i++){
      memset(vis,0,sizeof vis);
      if(findpath(i))ans++;
    }
    ans/=2;
    printf("Case %d: %d
",++kase,ans);
    // Case 1: 3
  }   

 // system("pause");
  return 0;
}
View Code

E - String LCM

 CodeForces - 1473B 

类似牛客多校,判断两个字符串是否有lcm可以在5*max(lena,lenb) 的时间以内判断出来。

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+500;
typedef long long ll;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
int main(){
  int t;cin>>t;
  while(t--){
    string a,b;cin>>a>>b;
    int lena=a.size(),lenb=b.size();
    int flag=1;
    for(int i=0;i<=5*max(lena,lenb);i++){
        if(a[i%lena]!=b[i%lenb]){
            flag=0;
            break;
        }
    }
    if(!flag)puts("-1");
    else {
        int len=lcm(lena,lenb);
        for(int i=0;i<len;i++)cout<<a[i%lena];
            cout<<endl;
    }

  }

    // system("pause");
    return 0;

}
View Code

 

A - Two Arrays And Swaps

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+500;
int a[N],b[N];
int main(){
  int t;cin>>t;
  while(t--){
    int n,k;cin>>n>>k;
    int sum=0;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum+=a[i];
    for(int i=1;i<=n;i++)scanf("%d",&b[i]);
      sort(a+1,a+1+n);
      sort(b+1,b+1+n);
      int pos=1;
      while(pos<=k){
        if(a[pos]<b[n-pos+1])sum+=b[n-pos+1]-a[pos];
        pos++;
      }
      // cout<<"test :";
      cout<<sum<<endl;
  }


  // system("pause");
  return 0;
}
View Code

B - Array Cancellation

 CodeForces - 1405B 

考虑每当出现需要  -1 +1 的免费操作,实际上就是前缀和,出现需要  +1   -1  的情况:实际上是前缀和最小的情况。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+500;
typedef long long ll;
// int a[N];
int main(){
  int t;cin>>t;
  while(t--){
    int n;cin>>n;
    ll sum=0,ans=1e18;
    for(int i=1;i<=n;i++){
    // cout<<"test :";
      ll x;
      scanf("%lld",&x),sum+=x,ans=min(ans,sum);
    }

      // cout<<"ans : ";
      cout<<-ans<<endl;
  }


  // system("pause");
  return 0;
}
View Code

A - Array Destruction

 CodeForces - 1474C 

每次操作完后剩余的最大的数一定要被下一次用到,枚举开始的点,复杂度O( n ^ 2)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e3+500;
const int maxm=1e6+500;
ll a[N];
// vector<int>G[N];
vector<int>vec[maxm];
vector<pair<ll,ll> >path,curpath;
int n;
// bool vis[N]; 
ll cnt[maxm];
int check(int x,int y){

  curpath.clear();
    vector<int>vec;
    
    vec.push_back(a[x]);vec.push_back(a[y]);
    curpath.push_back(make_pair(a[x],a[y]));
    int pos=n-1;
      int tmp;

      if(a[x]>a[y])tmp=a[x];
      else tmp=a[y];
      
      cnt[a[x]]--;cnt[a[y]]--;

    while(1){

      // cnt[a[x]]--;cnt[a[y]]--;
      // cnt[tmp]--;
      
      while(pos>0&&cnt[a[pos]]==0)pos--;
      
      if(pos==0)break;

      if(cnt[ tmp-a[pos] ]==0){
        for(int i=0;i<vec.size();i++)cnt[ vec[i] ]++;
        return false;
      }

      curpath.push_back(make_pair(a[pos],tmp-a[pos]));
      vec.push_back(a[pos]);vec.push_back(tmp-a[pos]);

      cnt[a[pos]]--;cnt[tmp-a[pos]]--;
      tmp=a[pos];

    }

    return true;
}
int main(){
    int t;cin>>t;
    while(t--){
      path.clear();

      cin>>n;
      n*=2;
      memset(cnt,0,sizeof cnt);

      for(int i=1;i<=n;i++)scanf("%lld",&a[i]),cnt[a[i]]++;      
      sort(a+1,a+1+n);

      // for(int i=1;i<=n;i++){
      //   for(int j=i+1;j<=n;j++){
      //     ll tmp=a[i]+a[j];
      //     if(vec[ tmp ].empty())continue;
      //     for(int k=0;k<vec[tmp].size();k++){
      //       G[ vec[tmp][k] ].push_back(j);
      //       G[ vec[tmp][k] ].push_back(i); 
      //     }
      //   }
      // }
    
      bool flag=0;
      int ans=-1;
      for(int i=1;i<n;i++){
          if(check(i,n)){
            flag=1;
            ans=a[i]+a[n];
            path=curpath;
            break;
          }
        
      }
      
      if(!flag)puts("NO");
      
      else {
        puts("YES");
        cout<<ans<<endl;
        for(int i=0;i<path.size();i++){
          // cout<<"test : ";
          printf("%lld %lld
",path[i].first,path[i].second);
        }
      }

      // for(int i=1;i<=n;i++)cnt[a[i]]--;
    
    }


 // system("pause");
  return 0;
}
View Code

B - 13th Labour of Heracles

 CodeForces - 1466D 

当k变大,实际上会把点权最大的贡献+1,

#include<bits/stdc++.h>
using namespace std;
#define mkp make_pair
const int N=1e5+500;
typedef long long ll;
// ll x[N],y[N];
// map<pair<ll,ll>,ll>mp;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll w[N],deg[N];
vector<ll>vec;
int main(){
  // cout<<gcd(0,0)<<endl;
  int t;cin>>t;
  while(t--){
    vec.clear();
    int n;cin>>n;
    ll ans=0;
    for(int i=1;i<=n;i++)deg[i]=0,scanf("%lld",&w[i]),ans+=w[i];
      
      for(int i=1;i<n;i++){
        int u,v;scanf("%d %d",&u,&v);
        deg[u]++;deg[v]++;
      }
      for(int i=1;i<=n;i++){
        for(int j=1;j<deg[i];j++){
          vec.push_back(w[i]);
        }
      }

      sort(vec.begin(),vec.end(),greater<ll>());
      // cout<<"test : ";
      cout<<ans<<" ";
      for(int i=0;i<vec.size();i++){
        ans+=vec[i];
        printf("%lld ",ans);
      }
      puts("");
  }


  // system("pause");
  return 0;
}
View Code

E - Full Turn

 CodeForces - 1468F 

如果两个人的视线相遇,就是两个向量的夹角180度,把每个向量标准化以后,直接统计map。

#include<bits/stdc++.h>
using namespace std;
#define mkp make_pair
const int N=1e5+500;
typedef long long ll;
ll x[N],y[N];
map<pair<ll,ll>,ll>mp;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
int main(){
  // cout<<gcd(0,0)<<endl;
  int t;cin>>t;
  while(t--){
    mp.clear();
   int n;cin>>n;
   for(int i=1;i<=n;i++){
    ll x1,y1,x2,y2;
    scanf("%lld %lld %lld %lld",&x1,&y1,&x2,&y2);
    x[i]=x2-x1;y[i]=y2-y1;
    if(x[i]==0&&y[i]==0);

    else if(x[i]==0&&y[i]!=0){
      y[i]=y[i]/abs(y[i]);
    }
    else if(y[i]==0&&x[i]!=0){
      x[i]/=abs(x[i]);
    }
    else {
    ll g=gcd(x[i],y[i]);
    g=abs(g);
    x[i]/=g;y[i]/=g;      
    }

    mp[mkp(x[i],y[i])]++;
   }

   // for(int i=1;i<=n;i++){
   //  cout<<"test : ";
   //  cout<<x[i]<<" "<<y[i]<<endl;
    
   // }

   ll ans=0;
   for(int i=1;i<=n;i++){
    if(mp[mkp(-x[i],-y[i])])ans+=mp[mkp(-x[i],-y[i])];
   }
   // cout<<"ans : ";
   cout<<ans/2<<endl;

  }


  // system("pause");
  return 0;
}
View Code
原文地址:https://www.cnblogs.com/littlerita/p/14315107.html