A.3583

n根木棍是否能分成相等两堆。

背包dp,首先求和sum,如果为偶数就说明不行,否则考虑做一个sum/2大小的背包。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. int main()
  5. {
  6. int n,w[];
  7. while(scanf("%d",&n)!=EOF)
  8. {
  9. int sum=;
  10. for(int i=;i<=n;i++)scanf("%d",&w[i]),sum+=w[i];
  11. bool dp[];
  12. memset(dp,,sizeof dp);
  13. dp[]=;
  14. for(int i=;i<=n;i++)
  15. for(int j=sum/;j>=w[i];j--)
  16. dp[j]=dp[j]|dp[j-w[i]];
  17. printf("%s\n",dp[sum/]&&sum%==?"Yes":"No");
  18. }
  19. return ;
  20. }

A.cpp

B.5146

单身狗在[l,r]之间且二进制中1的数量最多的数,若有多个输出最小的。

贪心,可以发现想要二进制最多,那么一定从最低位开始。

那么想要在[l,r]之间,先把l变成二进制,贪心即可(想想为什么)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define ll __int64
  5. int main()
  6. {
  7. int t;
  8. scanf("%d",&t);
  9. while(t--)
  10. {
  11. int a[]={},p=;
  12. ll l,r,ans;
  13. scanf("%I64d%I64d",&l,&r);
  14. ans=l;
  15. while(l)
  16. {
  17. a[p++]=l&;
  18. l>>=;
  19. }
  20. for(int i=;i<=;i++)
  21. {
  22. if(a[i]==&&ans+(1LL<<i)<=r)
  23. {
  24. ans+=1LL<<i;
  25. a[i]=;
  26. }
  27. }
  28. printf("%I64d\n",ans);
  29. }
  30. return ;
  31. }

B.cpp

C.3153

n个点m条无向边,问必须经过S<=10个点再回到起点0的最短路。

dijstra+状压dp,考虑对每个S跑一边dijstra,求出S到每个点的最短路。

dp[i][j]代表状态为i,现在在j点的最短路。

  1. #include <bits/stdc++.h>
  2. typedef long long ll;
  3. using namespace std;
  4. const int N=;
  5. vector<pair<int,int> > G[N];
  6. ll d[][N],dp[<<][];
  7. int a[],T,n,m;
  8. void dij(int p,int u)
  9. {
  10. for(int i=;i<n;i++)
  11. d[p][i]=1LL<<;
  12. d[p][u]=;
  13. queue<int> qu;
  14. qu.push(u);
  15. while(!qu.empty())
  16. {
  17. int x=qu.front();
  18. qu.pop();
  19. for(int i=;i<G[x].size();i++)
  20. {
  21. int v=G[x][i].first,c=G[x][i].second;
  22. if(d[p][v]>d[p][x]+c) d[p][v]=d[p][x]+c,qu.push(v);
  23. }
  24. }
  25. }
  26. int main()
  27. {
  28. scanf("%d",&T);
  29. while(T--)
  30. {
  31. scanf("%d%d",&n,&m);
  32. for(int i=;i<n;i++) G[i].clear();
  33. for(int i=,u,v,c;i<m;i++)
  34. {
  35. scanf("%d%d%d",&u,&v,&c);
  36. G[u].push_back({v,c});
  37. G[v].push_back({u,c});
  38. }
  39. scanf("%d",&m);
  40. int S=<<m;
  41. for(int i=;i<m;i++) scanf("%d",&a[i]),dij(i,a[i]);
  42. for(int i=;i<S;i++)
  43. for(int j=;j<m;j++)
  44. dp[i][j]=1LL<<;
  45. for(int i=;i<m;i++)
  46. dp[<<i][i]=d[i][];
  47. for(int s=;s<S;s++)
  48. {
  49. for(int i=;i<m;i++)
  50. if((<<i)&s)
  51. {
  52. for(int j=;j<m;j++)
  53. if(((<<j)&s)==)
  54. dp[s|(<<j)][j]=min(dp[s|(<<j)][j],dp[s][i]+d[i][a[j]]);
  55. }
  56. }
  57. ll ans=1LL<<;
  58. for(int i=;i<m;i++)
  59. ans=min(ans,dp[S-][i]+d[i][]);
  60. printf("%I64d\n",ans);
  61. }
  62. return ;
  63. }

C.cpp

D.3176

n<=30个值,每个值(0,2^16),求最小需要几个数的异或后值为0,每个数只能取1次。

背包dp,考虑dp[i]代表异或值为i的最少个数。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. int main()
  5. {
  6. int n,x,dp[<<];
  7. memset(dp,0x3f3f3f3f,sizeof dp);
  8. scanf("%d",&n);
  9. for(int i=;i<=n;i++)
  10. {
  11. scanf("%d",&x);
  12. for(int j=(<<)-;j>=;j--)
  13. dp[j^x]=min(dp[j^x],dp[j]+);
  14. dp[x]=;
  15. }
  16. if(dp[]==0x3f3f3f3f)printf("-1");
  17. else printf("%d",dp[]);
  18. }

D.cpp

E.3166

给一堆等级,和每个等级的区间,然后n个初始得分,每小时加1分,每个查询输出D小时后达到等级L的人数。

二分,从小到大排序,那么就是有多少个数ai+D在等级L的区间内,就相当于区间-D,然后二分左右段点。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int N=1e5+;
  5. int a[N],n,q,d,l,L,R;
  6. int main()
  7. {
  8. scanf("%d",&n);
  9. for(int i=;i<=n;i++)scanf("%d",&a[i]);
  10. sort(a+,a++n);
  11. scanf("%d",&q);
  12. while(q--)
  13. {
  14. scanf("%d%d",&d,&l);
  15. if(l==)L=,R=;
  16. if(l==)L=,R=;
  17. if(l==)L=,R=;
  18. if(l==)L=,R=;
  19. if(l==)L=,R=;
  20. if(l==)L=,R=;
  21. if(l==)L=,R=2e9+;
  22. int x1=lower_bound(a+,a++n,L-d)-a;
  23. int x2=upper_bound(a+,a++n,R-d)-a;
  24. printf("%d\n",x2-x1);
  25. }
  26. return ;
  27. }

E.cpp

F.2704

n个点m条无向边边权为1,从1出发问距离最远的点,如有多个输出编号最小的点,再输出距离,再输出有几个点。

dijstra模板题。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int N=2e4+;
  5. vector<int>G[N];
  6. int n,m,u,v;
  7. void bfs()
  8. {
  9. int d[N];
  10. memset(d,0x3f3f3f3f,sizeof d);
  11. queue<int>q;
  12. d[]=;
  13. q.push();
  14. while(!q.empty())
  15. {
  16. int u=q.front();q.pop();
  17. for(int i=;i<G[u].size();i++)
  18. {
  19. int v=G[u][i];
  20. if(d[v]>d[u]+)
  21. {
  22. d[v]=d[u]+;
  23. q.push(v);
  24. }
  25. }
  26. }
  27. int maxx=-,posi=,ans=;
  28. for(int i=;i<=n;i++)
  29. if(d[i]>maxx)maxx=d[i],posi=i;
  30. for(int i=;i<=n;i++)
  31. if(d[i]==maxx)ans++;
  32. cout<<posi<<" "<<maxx<<" "<<ans;
  33. }
  34. int main()
  35. {
  36. cin>>n>>m;
  37. for(int i=;i<m;i++)
  38. {
  39. cin>>u>>v;
  40. G[u].push_back(v);
  41. G[v].push_back(u);
  42. }
  43. bfs();
  44. return ;
  45. }

F.cpp

G.3168

n瓶奶生产商和生产日期保证2008年,m个生产商对应奶的保质期,给你一个开始的日期,每天最多喝一瓶,问最少几瓶会过期。

哈希+贪心,把每个日期转化成天,优先处理过期时间最早的。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int a[]={,,,,,,,,,,,,};
  4. vector<int>v[];
  5. int b[];
  6. int main()
  7. {
  8. std::ios::sync_with_stdio(false);
  9. map<string,int>m;
  10. int id=,n,x,y;
  11. char ch;
  12. string s;
  13. cin>>n;
  14. for(int i=;i<=n;i++)
  15. {
  16. cin>>s;
  17. if(m[s]==)
  18. m[s]=id++;
  19. cin>>x>>ch>>y;
  20. int day=;
  21. for(int j=;j<x;j++)
  22. day+=a[j];
  23. day+=y;
  24. v[m[s]].push_back(day);
  25. }
  26. int t;
  27. cin>>t;
  28. for(int i=;i<=t;i++)
  29. {
  30. cin>>s>>x;
  31. for(int j=;j<v[m[s]].size();j++)
  32. b[v[m[s]][j]+x]++;
  33. }
  34. cin>>x>>ch>>y;
  35. int day=;
  36. for(int j=;j<x;j++)
  37. day+=a[j];
  38. day+=y;
  39. int sum=;
  40. for(int i=;i<=day;i++)
  41. sum=sum+b[i];
  42. int p=day;
  43. for(int i=day+;i<;i++)
  44. {
  45. while(b[i]>)
  46. {
  47. if(p<i)
  48. p++,b[i]--;
  49. else
  50. {
  51. sum+=b[i];
  52. break;
  53. }
  54. }
  55. }
  56. cout<<sum<<endl;
  57. return ;
  58. }

G.cpp

H.3213

n<=8个题目选择k个难度总和<=p求方案数。

n很小,直接暴力dfs。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int v[],n,k,p,ans;
  4. void DFS(int pos,int s,int cnt)
  5. {
  6. if(s <= p && cnt == k) {ans++;return;}
  7. if(cnt > k || s > p) return;
  8. for(int i = pos; i < n; i++)
  9. {
  10. DFS(i + ,s + v[i],cnt + );
  11. }
  12. }
  13. int main()
  14. {
  15. int t; scanf("%d",&t);
  16. while(t--)
  17. {
  18. scanf("%d%d%d",&n,&k,&p);
  19. for(int i = ; i < n; i++) scanf("%d",&v[i]);
  20. ans = ;
  21. DFS(,,);
  22. printf("%d\n",ans);
  23. }
  24. return ;
  25. }

H.cpp

I.5069

给n*m的图,求一个四周全是‘.’的最大矩形。

思维,a为列前缀和,b为行前缀和,(i,j)---(i,k)那么第i行的a[i][k]-a[i][j]==k-j那么第i行j->k都是1,x=min(b[i][j],b[i][k])代表j向上或者k向上连续1的数量,然后只需要判断a[i-x+1][k]-a[i-x+1][j]==k-j,这就说明第i-x+1行j­->k都是1,复杂度O(n^3)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. int n,m;
  5. char G[][];
  6. int a[][],b[][];
  7. int main()
  8. {
  9. scanf("%d%d",&n,&m);
  10. for(int i=;i<=n;i++)
  11. scanf("%s",G[i]+);
  12. for(int i=;i<=n;i++)
  13. for(int j=;j<=m;j++)
  14. if(G[i][j]=='.')
  15. a[i][j]=a[i][j-]+,
  16. b[i][j]=b[i-][j]+;
  17. else
  18. a[i][j]=,
  19. b[i][j]=;
  20. //(i,j) (i,k)
  21. int maxx=;
  22. for(int i=;i<=n;i++)
  23. for(int j=;j<=m;j++)
  24. {
  25. for(int k=j;k<=m;k++)
  26. {
  27. if(a[i][k]-a[i][j]!=k-j)break;
  28. if(b[i][j]&&b[i][k])
  29. {
  30. int x=min(b[i][j],b[i][k]);
  31. while(a[i-x+][k]-a[i-x+][j]!=k-j)x--;
  32. maxx=max(maxx,x*(k-j+));
  33. }
  34. }
  35. }
  36. printf("%d",maxx);
  37. return ;
  38. }

I.cpp

J.4482

n个数的积为A,m个数的积为B,求A和B的gcd。

zdragon的O((n+m)*sqrt(1e9))

求A的所有素因子,求B的所有素因子,枚举所有素因子,答案就是素因子^(该素因子A有几个,该素因子B有几个)的积。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=;
  4. const int MD=;
  5. int a[N<<],b[N<<],cnt;
  6. bool f;
  7. map<int,int> ma,mma;
  8. long long quick_pow(long long x,int y)
  9. {
  10. long long ans=;
  11. while(y)
  12. {
  13. if(y&)
  14. {
  15. ans*=x;
  16. if(ans>MD||f) ans%=MD,f=true;
  17. }
  18. x*=x;
  19. if(x>MD||f) x%=MD,f=true;
  20. y>>=;
  21. }
  22. return ans;
  23. }
  24. int main()
  25. {
  26. int n,m;
  27. scanf("%d",&n);
  28. for(int i=,x;i<n;i++)
  29. {
  30. scanf("%d",&x);
  31. for(int j=;1LL*j*j<=x;j++)
  32. {
  33. if(x%j==)
  34. {
  35. if(!ma[j]) ma[j]=(++cnt),mma[cnt]=j;
  36. while(x%j==) a[ma[j]]++,x/=j;
  37. }
  38. }
  39. if(x>)
  40. {
  41. if(!ma[x]) ma[x]=(++cnt),mma[cnt]=x;
  42. a[ma[x]]++;
  43. }
  44. }
  45. scanf("%d",&m);
  46. for(int i=,x;i<m;i++)
  47. {
  48. scanf("%d",&x);
  49. for(int j=;1LL*j*j<=x;j++)
  50. {
  51. if(x%j==)
  52. {
  53. if(!ma[j]) ma[j]=(++cnt),mma[cnt]=j;
  54. while(x%j==) b[ma[j]]++,x/=j;
  55. }
  56. }
  57. if(x>)
  58. {
  59. if(!ma[x]) ma[x]=(++cnt),mma[cnt]=x;
  60. b[ma[x]]++;
  61. }
  62. }
  63. long long ans=;
  64. for(int i=;i<=cnt;i++)
  65. {
  66. ans=ans*quick_pow(1LL*mma[i],min(a[i],b[i]));
  67. if(ans>MD||f) ans%=MD,f=true;
  68. }
  69. if(f) printf("%09I64d\n",ans);
  70. else printf("%I64d\n",ans);
  71. return ;
  72. }

J.cpp O((n+m)*sqrt(1e9))

wff的O(n*m)

暴力gcd。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int inf =0x3f3f3f3f;
  4. #define ll long long
  5.  
  6. int a[],b[];
  7. int main()
  8. {
  9. ll ans1=,ans2=;
  10. int n,m;
  11. scanf("%d",&n);
  12. for(int i=;i<n;i++)
  13. {
  14. scanf("%d",&a[i]);
  15. }
  16. scanf("%d",&m);
  17. for(int i=;i<m;i++)
  18. {
  19. scanf("%d",&b[i]);
  20. }
  21. int flag=;
  22. for(int i=;i<n;i++)
  23. {
  24. for(int j=;j<m;j++)
  25. {
  26. int t=__gcd(a[i],b[j]);
  27. ans1=1ll *ans1 * t ;
  28. if(!flag&&ans1>= ) flag=;
  29. ans1%=;
  30. a[i]/=t;
  31. b[j]/=t;
  32. }
  33. }
  34. if(flag) printf("%09I64d",ans1% );
  35. else printf("%I64d",ans1% );
  36. return ;
  37. }

J.cpp O(n*m)

K.4426

n个人初始分ai,第一名+n分,第二名+n-1分,以此类推,如果一个人i是冠军那么他的得分大于等于其他所有人的得分,问有几个人可能是冠军。

贪心,首先按ai从小到大排序,得分最高的加1分,第二高加2分,以此类推,maxx=ai+n-i+1的最大值,如果一个人i是冠军,那么ai+n大于等于maxx。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int N=3e5+;
  5. int a[N],n,ans,sum;
  6. int main()
  7. {
  8. scanf("%d",&n);
  9. for(int i=;i<=n;i++)scanf("%d",&a[i]);
  10. sort(a+,a++n);
  11. for(int i=n;i>=;i--)ans=max(ans,a[i]+n-i+);
  12. for(int i=;i<=n;i++)if(a[i]+n>=ans)sum++;
  13. printf("%d",sum);
  14. return ;
  15. }

K.cpp

L.3457

给一个整数,输出重排列后的最小值。

贪心,首先第一个数不能为0,那么先取个不是0的最小放在第一个。然后按小到大输出。

  1. #include<stdio.h>
  2. #include<string.h>
  3. int main()
  4. {
  5. int i,j;
  6. char a[];
  7. while(scanf("%s",&a)!=EOF)
  8. {
  9. int b[]={},min=;
  10. for(i=;i<strlen(a);i++)
  11. {
  12. b[a[i]-'']++;
  13. if(a[i]-''<min&&a[i]-''!=)
  14. min=a[i]-'';
  15. }
  16. printf("%d",min);
  17. b[min]--;
  18. for(i=;i<;i++)
  19. {
  20. for(j=;j<b[i];j++)
  21. printf("%d",i);
  22. }
  23. printf("\n");
  24. }
  25. return ;
  26. }

L.cpp

M.2609

n个点m条无向边最多k次操作使得边花费为0,求1到n的最短路。

堆优化的dijstra+dp,分成k层,dp[k][i]表示已经让k条边花费变成0到i的最短路。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int maxn=1e4+;
  5. const int maxm=5e4+;
  6. const int maxk=+;
  7.  
  8. inline int read() {
  9. int x=,f=;char c=getchar();
  10. for(;c<''||''<c;c=getchar())if(c=='-')f=-;
  11. for(;''<=c&&c<='';c=getchar())x=(x<<)+(x<<)+c-'';
  12. return x*f;
  13. }
  14.  
  15. vector< pair<int,int> >G[maxn];
  16. int d[maxk][maxn],vis[maxk][maxn];
  17. int n,m,k;
  18. struct edge
  19. {
  20. int v,k,w;
  21. bool operator<(const edge& D)const{
  22. return w>D.w;
  23. }
  24. };
  25. int dij()
  26. {
  27. for(int i=;i<=k;i++)for(int j=;j<=n;j++)d[i][j]=0x3f3f3f3f,vis[i][j]=;
  28. priority_queue<edge>q;
  29. q.push({,,});
  30. d[][]=;
  31. while(!q.empty())
  32. {
  33. edge u=q.top();q.pop();
  34. //printf("%d %d\n",u.v,u.w);
  35. if(u.v==n)return u.w;
  36. if(vis[u.k][u.v])continue;
  37. vis[u.k][u.v]=;
  38. for(auto x:G[u.v])
  39. {
  40. int v=x.first;
  41. int w=x.second;
  42. if(d[u.k][v]>u.w+w)
  43. q.push({v,u.k,d[u.k][v]=u.w+w});
  44. if(u.k<k&&d[u.k+][v]>u.w)
  45. q.push({v,u.k+,d[u.k+][v]=u.w});
  46. }
  47. }
  48. return 0x3f3f3f3f;
  49. }
  50. int main()
  51. {
  52. n=read(),m=read(),k=read();
  53. for(int i=,u,v,w;i<=m;i++)
  54. {
  55. u=read(),v=read(),w=read();
  56. G[u].push_back({v,w});
  57. G[v].push_back({u,w});
  58. }
  59. printf("%d\n",dij());
  60. return ;
  61. }

M.cpp

集训队日常训练20180518-DIV1的更多相关文章

  1. 集训队日常训练20181117 DIV2

    大佬们一顿操作猛如虎,拼命AC强啊 4262: 区间异或  Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByteTotal ...

  2. 集训队日常训练20181201 C 1003 : 种类数

    时间限制(普通/Java):2000MS/6000MS     内存限制:65536KByte总提交: 8            测试通过:5 描述 一共有 n个数,第 i 个数是 xi ,其中xi  ...

  3. 集训队日常训练20181201 E 1005 : 小蝌蚪

    时间限制(普通/Java):500MS/1500MS     内存限制:65536KByte总提交: 25            测试通过:5 描述 有 n 个装着小蝌蚪的水缸排成一排,你拥有一个无限 ...

  4. 集训队日常训练20181124 DIV2

    急急忙忙要出去比赛就拉了一场有点sb的题目 5202: 网络寻路  时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte总提交: 15            ...

  5. 集训队日常训练20181110 DIV2 题解及AC代码

    4375: 孪生素数  Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByteTotal Submit: 324       ...

  6. 集训队日常训练20180525-DIV2

    A.2295 求有多少素数对和等于n. 暴力. #include <bits/stdc++.h> using namespace std; int ss(int n) { ,a=sqrt( ...

  7. 集训队日常训练20180525-DIV1

    A.2805 N*M的图,每次浇水(X1,Y1)-(X2,Y2)围成的矩形,问最后有多少点被浇水了. 暴力. #include<bits/stdc++.h> using namespace ...

  8. 集训队日常训练20180518-DIV2

    A.3232 n个物品,换取要花积分,问刚好花完积分能换最大多少价值的物品. 多重背包. #include <bits/stdc++.h> using namespace std; ]; ...

  9. 集训队日常训练20180513-DIV1

    A.3132 给一个有向图,问能否从任意点出发都能进入一个环中. 深搜. #include<bits/stdc++.h> using namespace std; ; vector< ...

随机推荐

  1. 对XP上的KiFastSystemCall进行浅析

    Windows API的系统调用过程通过KiFastSystemCall或int 2e进入内核,本文仅对XP上的KiFastSystemCall进行浅析. 以ntdll!ZwCreateProcess ...

  2. Android基础控件TextView

    1.常用属性 <TextView android:id="@+id/text11" //组件id android:layout_width="match_paren ...

  3. 模板——AC自动机

    传送门:QAQQAQ 定义nxt[u]=v表示从u开始不断沿着失配边跳到的第一个是标记点的端点v,那么我们再匹配时沿着last跳,每跳到一个last,它就一定对应一个模式串,所以效率是非常高的. 和K ...

  4. springmvc前端控制器拦截路径的配置报错404

    1.拦截"/",可以实现现在很流行的REST风格.很多互联网类型的应用很喜欢这种风格的URL.为了实现REST风格,拦截除了jsp的所有. 2.拦截/*,拦截所有访问,会导致404 ...

  5. neo4j 实战、实例、示例 创建电影关系图 -1

    1. 创建关系 因为代码占篇幅太大,创建整个"电源关系图"的代码在文章最下方. 2. 简单分析创建语句 2.1 创建电影节点 CREATE (TheMatrix:Movie {ti ...

  6. vue页面刷新数据丢失问题

    参考: https://blog.csdn.net/aliven1/article/details/80743470          https://blog.csdn.net/liang37712 ...

  7. 订单风险系统BI

    最近被公司叫去协助传统做维表查询服务,项目已经做完.和前端联调过程发现oracle对查询 sql和产品设计还是挺重要的.不能全部堆给代码去做,如何方便代码,代码优化到最高性能才是首要解决的事,前端才能 ...

  8. Create STKNetDiskC Instance Error

    关于Create STKNetDiskC Instance Error错误的解决方法 这个错误可能出现在: AM8 附件直接存网盘的时候 报错 解决方法步骤如下: 在出现该错误的机器上,先将AM及 m ...

  9. 阿里云提供全托管 ZooKeeper

    自 2010 年左右第一次引入以来,Apache ZooKeeper 目前在阿里巴巴集团内部已经有了将近 10 年的发展,使用的场景非常广泛,基于 ZooKeeper 强一致性的特点,被用在了分布式锁 ...

  10. C语言中结构体的深拷贝和浅拷贝

    C++ 的浅拷贝和深拷贝(结构体) 拷贝有两种:深拷贝,浅拷贝 浅拷贝:拷贝过程中是按字节复制的,对于指针型成员变量只复制指针本身,而不复制指针所指向的目标 (1)结构体中不存在指针成员变量时 typ ...