xjoi奋斗群群赛13

来源:互联网 发布:精美的php个人网站源码 编辑:程序博客网 时间:2024/06/06 00:09

群赛地址;

https://vjudge.net/contest/186396#problem

A - Dima and Guards

 CodeForces - 366A 

题意:这是一道水题.

题解:

#include<iostream>#include<algorithm>using namespace std;int main(){int n,a,b,c,d;int p=-1,x,y;cin>>n;for(int i=1;i<=4;i++){cin>>a>>b>>c>>d;if(min(a,b)+min(c,d)<=n){p=i;x=min(a,b);y=n-x;}}if(p==-1)cout<<-1;else cout<<p<<' '<<x<<' '<<y;}

B - Dima and To-do List

 CodeForces - 366B 

题意:一个序列,每隔k个数取一个数,求最小和的首先取位置.

题解:

#include<bits/stdc++.h>using namespace std;int n,k,a[100010],sum[100010];int main(){scanf("%d%d",&n,&k);for(int i=1;i<=n;i++){scanf("%d",a+i);}for(int i=1;i<=k;i++){for(int j=i;j<=n;j+=k){sum[i]+=a[j];}}int minn=sum[1],p=1;for(int i=2;i<=k;i++){if(minn>sum[i]){minn=sum[i];p=i;}}printf("%d",p);}


C - Dima and Salad

 CodeForces - 366C 

题意:给出一个序列,求和为0的序列使一个参数最大.

思路:背包

题解:

#include<bits/stdc++.h>using namespace std;const int add=1e4;int n,k,a[110],b[110],w[110],dp[110][110010],sum[110][110010];int main(){cin>>n>>k;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n;i++) cin>>b[i];for(int i=1;i<=n;i++) w[i]=b[i]*k-a[i];for(int i=1;i<=n;i++){dp[i][w[i]+add]=1;sum[i][w[i]+add]=max(sum[i][w[i]+add],a[i]);for(int j=0;j<=110000;j++){if(dp[i-1][j]){dp[i][j]=1;sum[i][j]=max(sum[i][j],sum[i-1][j]);dp[i][j+w[i]]=1;sum[i][j+w[i]]=max(sum[i][j+w[i]],sum[i-1][j]+a[i]);}}}if(dp[n][add])printf("%d\n",sum[n][add]);else printf("-1\n");}

D - Dima and Trap Graph

 CodeForces - 366D 

题意:一个人要在一个图中从1走到n,图中每个边有一个l值,r值,那个人的数在l,r之间才能通过.问那个人能取的数的种类数.

失败的代码:

#include<iostream>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<cstring>#include<cstdlib>using namespace std;const int MAXN=1000;const int INF=0x3f3f3f3f;struct Edge {int from, to;bitset < 1001 > cap;bitset < 1001 > flow;Edge(int u,int v,int c,int f) : from(u), to(v) {this->cap.reset();this->flow.reset();for(int i=c;i<=f;i++) {this->cap.set(i);}}};struct EdmondsKarp {int n, m, l;vector < Edge > edges;vector < int > G[MAXN];bitset < 1001 > a[MAXN];int p[MAXN];void init() {for(int i = 0; i < n; ++i) {G[i].clear();}edges.clear();}void AddEdge(int from, int to, int lef, int rig) {edges.push_back(Edge(from, to, lef, rig));edges.push_back(Edge(to, from, lef, rig)); //反向弧l = edges.size();G[from].push_back(l - 2);G[to].push_back(l - 1);}int Maxflow(int s, int t) {cout<<"BEGIN:\n";bitset < 1001 > flow;for(;;) {cout<<"new queue:\n";system("pause");queue < int > Q;Q.push(s);for(int i=1;i<=n;i++) {a[i].reset();}a[s].set();//初始源点有无限个物品while(!Q.empty()) {int x = Q.front();Q.pop();cout<<"new repeat:x = "<<x<<endl;for(int i = 0; i < G[x].size(); ++i) {cout<<"(1)";Edge &e = edges[G[x][i]];cout<<"new point: point = "<<e.to<<endl;if(a[e.to].none() && ((e.flow & a[x]) != a[x]) ) { // 查找任意边流动物品cout<<"(2)";p[e.to] = G[x][i];//a[e.to] = min(a[x], e.cap - e.flow);a[e.to] = (a[x] | a[e.to]) & e.cap;cout<<"new bit: bit = "<<a[e.to].count()<<endl;if(a[e.to].any()) {Q.push(e.to);cout<"(3)";}}}cout<<"(4)";if(a[t].any()) { //如果有增广路,退出cout<<"(5)";break;}}if(a[t].none()) { //没有增广路,现在的结果即为最大流cout<<"(6)";break;}for(int u = t; u != s; u = edges[p[u]].from) { // 反向修改流量cout<<"(7)";edges[p[u]].flow |= a[t];cout<<"edges_flow: "<<p[u]<<" "<<edges[p[u]].flow.count()<<endl;edges[p[u] ^ 1].flow ^= a[t];}flow |= a[t];//增加总流量//cout<<"flow = "<<flow.count()<<" a[t] = "<<a[t]<<endl;}return flow.count();}};int main() {EdmondsKarp ED;scanf("%d%d",&ED.n,&ED.m);int a,b,c,d;for(int i=1;i<=ED.m;i++) {scanf("%d%d%d%d",&a,&b,&c,&d);ED.AddEdge(a,b,c,d);}cout<<"================================================="<<ED.Maxflow(1,ED.n);}

tijie

#include<bits/stdc++.h>using namespace std;const int maxn = 1e4+5;const int INF = 0x3f3f3f3f;struct node{    int v, l, r;    node(int vv, int ll, int rr): v(vv), l(ll), r(rr) {}};int n, m, ans, recl[maxn], recr[maxn];bool vis[maxn], book[maxn];vector<node> g[maxn];void dfs(int u, int l, int r){    if(u == n)    {        ans = max(ans, r-l+1);        return ;    }    for(int i = 0; i < g[u].size(); i++)    {        int v = g[u][i].v;        int L = g[u][i].l;        int R = g[u][i].r;        if(!vis[v])        {            int tl = max(L, l);            int tr = min(R, r);            if(tl <= tr)            {                if(ans != -1 && tr-tl+1 <= ans) continue;//                if(book[v] && tl >= recl[v] && tr <= recr[v]) continue ;//                book[v] = 1;                recl[v] = tl, recr[v] = tr;                vis[v] = 1;                dfs(v, tl, tr);                vis[v] = 0;            }        }    }}int main(void){    while(cin >> n >> m)    {        memset(vis, 0, sizeof(vis));        memset(book, 0, sizeof(book));        for(int i = 1; i <= n; i++)            g[i].clear();        for(int i = 1; i <= m; i++)        {            int u, v, l, r;            scanf("%d%d%d%d", &u, &v, &l, &r);            g[u].push_back(node(v, l, r));            g[v].push_back(node(u, l, r));        }        ans = -1;        dfs(1, -INF, INF);        if(ans == -1) puts("Nice work, Dima!");        else printf("%d\n", ans);    }    return 0;}

E - Dima and Magic Guitar

 CodeForces - 366E 


题意:一个人弹吉他,有一些弦和片,移动到另一个弦和片的距离为曼哈顿距离.给出他要弹的曲子和吉他上各种弦和片的生成音符,求他最大的单次移动距离.

思路:由于只要求单次距离,所以预处理n*m一边就行了.

题解:

#include<iostream>  #include<cstdio>  #include<cstring>  using namespace std;  int n,m,k,s;  int f[10][2],b[10][2]; int main(){      memset(f,192,sizeof(f));      memset(b,63,sizeof(b));      scanf("%d%d%d%d",&n,&m,&k,&s);      for(int i=1;i<=n;i++){          for(int j=1;j<=m;j++){              int a;              scanf("%d",&a);              f[a][0]=max(f[a][0],i+j); f[a][1]=max(f[a][1],i-j);              b[a][0]=min(b[a][0],i+j); b[a][1]=min(b[a][1],i-j);          }      }      int p,q,ans=0;      for(int i=0;i<s;i++,p=q){          scanf("%d",&q);          if(i){              int t1=f[p][0]-b[q][0];              int t2=f[q][1]-b[p][1];              int t3=f[p][1]-b[q][1];              int t4=f[q][0]-b[p][0];              ans=max(ans,max(t1,max(t2,max(t3,t4))));          }      }      printf("%d\n",ans);      return 0;  }  





原创粉丝点击