• 计蒜之道复赛 B D F


    B题是一个简单的模拟

    求一下两个点中间每过deta的整数点

    然后更新一下每个点的最后一次经过就好了

     1 #include<bits/stdc++.h>
     2 #define cl(a,b) memset(a,b,sizeof(a))
     3 #define debug(x) cerr<<#x<<"=="<<(x)<<endl
     4 using namespace std;
     5 
     6 const int maxn=300+10;
     7 
     8 int gcd(int a,int b){return a?gcd(b%a,a):b;}
     9 int abs(int a){if(a>0)return a;return -a;}
    10 
    11 int a[maxn][maxn];
    12 
    13 int main()
    14 {
    15     int n,m;
    16     scanf("%d%d",&n,&m);
    17     cl(a,0);
    18     for(int i=1;i<=n;i++)
    19     {
    20         int x1,y1,x2,y2,dx,dy;
    21         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    22         dx=x2-x1;
    23         dy=y2-y1;
    24         int k=gcd(abs(dx),abs(dy));
    25         dx/=k,dy/=k;
    26         x2+=dx;
    27         while(x1!=x2)
    28         {
    29 //            debug(x1),debug(y1);
    30             a[x1][y1]=i;
    31             x1+=dx,y1+=dy;
    32         }
    33     }
    34     int q;
    35     scanf("%d",&q);
    36     while(q--)
    37     {
    38         int x,y;
    39         scanf("%d%d",&x,&y);
    40         printf("%d
    ",a[x][y]);
    41     }
    42     return 0;
    43 }/*
    44 
    45 5 8
    46 2 5 5 2
    47 5 2 3 8
    48 8 4 1 4
    49 2 2 5 8
    50 8 7 4 1
    51 4
    52 3 4
    53 5 2
    54 6 4
    55 3 5
    56 
    57 */

    D是一个最短路

    而且用到了虚点的操作

    每个城市群都是一个虚点

    也就是对每个城市群需要加两个点 u'和u''

    在每个群内的城市连自己的城市群是

    u'->v

    v->u''

    然后每个城市群之间

    u'->v''

    v'->u''

    直接跑一遍spfa就行

    需要注意的是:

    1.n和m没有规定谁大谁小 所以加点的时候n*2+i和n+i是会冲突的

    2.因为最大的值是2e5*2e6>2^31-1 所以ans要用ll存

    3.由于上一点的存在 inf也要改……

      1 #include<bits/stdc++.h>
      2 #define cl(a,b) memset(a,b,sizeof(a))
      3 #define debug(x) cerr<<#x<<"=="<<(x)<<endl
      4 using namespace std;
      5 typedef long long ll;
      6 
      7 const int MAXN=4e5+10;
      8 const ll INF=2e12;
      9 
     10 struct Edge
     11 {
     12     int v;
     13     int cost;
     14     Edge(int _v=0,int _cost=0):v(_v),cost(_cost) {}
     15 };
     16 
     17 vector<Edge>E[MAXN];
     18 
     19 void addedge(int u,int v,int w)
     20 {
     21     E[u].push_back(Edge(v,w));
     22 }
     23 
     24 bool vis[MAXN];
     25 int cnt[MAXN];
     26 ll dist[MAXN];
     27 int n,m;
     28 int start,over;
     29 
     30 ll SPFA(int start,int n)
     31 {
     32     for(int i=0;i<n+m*2+10;i++)
     33     {
     34         dist[i]=INF;
     35         vis[i]=false;
     36     }
     37     vis[start]=true;
     38     dist[start]=0;
     39     queue<int>que;
     40     while(!que.empty())que.pop();
     41     que.push(start);
     42     memset(cnt,0,sizeof(cnt));
     43     cnt[start]=1;
     44     while(!que.empty())
     45     {
     46         int u=que.front();
     47         que.pop();
     48         vis[u]=false;
     49         for(int i=0; i<E[u].size(); i++)
     50         {
     51             int v=E[u][i].v;
     52             if(dist[v]>dist[u]+E[u][i].cost)
     53             {
     54                 dist[v]=dist[u]+E[u][i].cost;
     55                 if(!vis[v])
     56                 {
     57                     vis[v]=true;
     58                     que.push(v);
     59                     if(++cnt[v]>n) return -1;
     60                 }
     61             }
     62         }
     63     }
     64     return dist[over];
     65 }
     66 
     67 int main()
     68 {
     69     scanf("%d%d",&n,&m);
     70     for(int i=1;i<=m;i++)
     71     {
     72         int k;
     73         scanf("%d",&k);
     74         for(int j=0;j<k;j++)
     75         {
     76             int x;
     77             scanf("%d",&x);
     78             addedge(x,n+m+i,0);
     79             addedge(n+i,x,0);
     80         }
     81     }
     82     int m1;
     83     scanf("%d",&m1);
     84     for(int i=0;i<m1;i++)
     85     {
     86         int u,v,w;
     87         scanf("%d%d%d",&u,&v,&w);
     88         addedge(u,v,w);
     89         addedge(v,u,w);
     90     }
     91     int m2;
     92     scanf("%d",&m2);
     93     for(int i=0;i<m2;i++)
     94     {
     95         int u,v,w;
     96         scanf("%d%d%d",&u,&v,&w);
     97         addedge(n+m+u,n+v,w);
     98         addedge(n+m+v,n+u,w);
     99     }
    100     scanf("%d%d",&start,&over);
    101     ll ans=SPFA(start,n);
    102     printf("%lld
    ",ans>=INF?-1:ans);
    103     return 0;
    104 }/*
    105 
    106 5 4
    107 2 5 1
    108 2 2 4
    109 1 3
    110 2 3 4
    111 2
    112 1 2 9
    113 1 5 18
    114 2
    115 1 2 6
    116 1 3 10
    117 1 5
    118 
    119 */

    F是一个状压dp

    (虽然没有16这么性感的数字 但是18也很明显了~

    第一维表示当前状态 01表示是否删除

    第二维表示已经删除的步数

    用l r来枚举区间

    数据范围不是很大(2^n)*n*n是可以容忍的

    (也是调了好久啊……

     1 #include<bits/stdc++.h>
     2 #define cl(a,b) memset(a,b,sizeof(a))
     3 #define debug(x) cerr<<#x<<"=="<<(x)<<endl
     4 using namespace std;
     5 typedef long long ll;
     6 
     7 const int maxn=20;
     8 const int mod=1000000007;
     9 
    10 int gcd(int a,int b)
    11 {
    12     return a?gcd(b%a,a):b;
    13 }
    14 
    15 bool check(int x,int y)
    16 {
    17     return x&(1<<y);
    18 }
    19 
    20 int n,k;
    21 int a[maxn];
    22 int dp[(1<<maxn)][maxn];
    23 
    24 void solve()
    25 {
    26     for(int i=0; i<(1<<n); i++)
    27     {
    28         for(int l=0; l<n; l++)
    29         {
    30             int tmp=i;
    31             if(check(i,l))
    32             {
    33                 int tmp1=a[l];
    34                 for(int r=l; r<n; r++)
    35                 {
    36                     if(check(i,r))
    37                     {
    38                         tmp^=(1<<r);
    39                         tmp1=gcd(tmp1,a[r]);
    40                         if(tmp1<k) break;
    41                         for(int j=1; j<=n; j++)
    42                         {
    43                             dp[i][j]=(dp[i][j]+dp[tmp][j-1])%mod;
    44                         }
    45                     }
    46                 }
    47             }
    48         }
    49     }
    50 }
    51 
    52 int main()
    53 {
    54     scanf("%d%d",&n,&k);
    55     cl(a,0),cl(dp,0);
    56     for(int i=0; i<n; i++)
    57     {
    58         scanf("%d",&a[i]);
    59     }
    60     dp[0][0]=1;
    61     solve();
    62     ll ans=0;
    63     for(int i=1; i<=n; i++)
    64     {
    65         ans+=1ll*i*dp[(1<<n)-1][i];
    66         ans%=mod;
    67     }
    68     printf("%lld
    ",ans);
    69     return 0;
    70 }/*
    71 
    72 4 1
    73 1 1 1 1
    74 
    75 */
  • 相关阅读:
    传递函数笔记
    模糊控制算法详细讲解
    SDRAM学习笔记
    基于STM32的CRC校验说明
    如何把图片设置成24位图/8位图??
    C2MIF软件使用说明
    ROM和RAM的内存详细说明
    Logback配置
    Logback使用
    common-logging源码解析
  • 原文地址:https://www.cnblogs.com/general10/p/6980161.html
Copyright © 2020-2023  润新知