zoukankan      html  css  js  c++  java
  • Codeforces Round #364 (Div. 2)

    还是4个1a

    记录代码

    A

     1 //#define txtout
     2 //#define debug
     3 #include<bits/stdc++.h>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 typedef long long LL;
     7 const double pi=acos(-1.0);
     8 const double eps=1e-8;
     9 const int inf=0x3f3f3f3f;
    10 const int M=1e5+10;
    11 int n,m;
    12 int a[M];
    13 bool v[M];
    14 void solve(){
    15 
    16 }
    17 int main(){
    18     #ifdef txtout
    19     freopen("in.txt","r",stdin);
    20     freopen("out.txt","w",stdout);
    21     #endif // txtout
    22     while(~scanf("%d",&n)){
    23         int sum=0;
    24         for(int i=1;i<=n;i++){
    25             scanf("%d",&a[i]);
    26             sum+=a[i];
    27             v[i]=false;
    28         }
    29         int avg=sum*2/n;
    30         for(int i=1;i<=n;i++){
    31             bool flag=false;
    32             for(int j=1;j<=n;j++){
    33                 if(v[j]) continue;
    34                 for(int k=j+1;k<=n;k++){
    35                     if(v[k]) continue;
    36                     if(a[j]+a[k]==avg){
    37                         flag=true;
    38                         printf("%d %d
    ",j,k);
    39                         v[j]=true;
    40                         v[k]=true;
    41                         break;
    42                     }
    43                 }
    44                 if(flag) break;
    45             }
    46         }
    47     }
    48     return 0;
    49 }
    View Code

    B

     1 //#define txtout
     2 //#define debug
     3 #include<bits/stdc++.h>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 typedef long long LL;
     7 const double pi=acos(-1.0);
     8 const double eps=1e-8;
     9 const int inf=0x3f3f3f3f;
    10 const int M=1e5+10;
    11 int n,m;
    12 set<int> sx,sy;
    13 int main(){
    14     #ifdef txtout
    15     freopen("in.txt","r",stdin);
    16     freopen("out.txt","w",stdout);
    17     #endif // txtout
    18     while(~scanf("%d%d",&n,&m)){
    19         sx.clear();
    20         sy.clear();
    21         LL tn=n;
    22         bool flag=false;
    23         int x,y;
    24         while(m--){
    25             scanf("%d%d",&x,&y);
    26             sx.insert(x);
    27             sy.insert(y);
    28             LL sum=0;
    29             x=sx.size();
    30             y=sy.size();
    31             sum=tn*tn-tn*x-tn*y+1LL*x*y;
    32             if(flag) putchar(' ');
    33             printf("%I64d",sum);
    34             flag=true;
    35         }
    36         puts("");
    37     }
    38     return 0;
    39 }
    View Code

    C  

    题意  给一个串,问选一个最短的子串 ,使得子串中有原串所有类型的字符

    比赛是用二分,  枚举起点,二分终点 ,通过前n项和 O56判出是否满足

     1 //#define txtout
     2 //#define debug
     3 #include<bits/stdc++.h>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 typedef long long LL;
     7 const double pi=acos(-1.0);
     8 const double eps=1e-8;
     9 const int inf=0x3f3f3f3f;
    10 const int M=1e5+10;
    11 int n;
    12 char a[M];
    13 int sum[64][M];
    14 int toid(char c){
    15     if(c>='a'&&c<='z') return c-'a';
    16     return c-'A'+26;
    17 }
    18 void init(){
    19     for(int i=0;i<52;i++){
    20         sum[i][0]=0;
    21     }
    22     sum[toid(a[0])][0]=1;
    23     for(int i=1;i<n;i++){
    24         for(int j=0;j<52;j++){
    25             sum[j][i]=sum[j][i-1];
    26         }
    27         sum[toid(a[i])][i]++;
    28     }
    29 }
    30 bool judge(int s,int mid){
    31     for(int i=0;i<52;i++){
    32         if(sum[i][n-1]==0) continue;
    33         int total=sum[i][mid];
    34         if(s>0) total-=sum[i][s-1];
    35         if(total<=0) return false;
    36     }
    37     return true;
    38 }
    39 int bs(int s){
    40     int L=s,R=n-1,result=-1;
    41     while(L<=R){
    42         int mid=(L+R)>>1;
    43         if(judge(s,mid)){
    44             result=mid;
    45             R=mid-1;
    46         }
    47         else{
    48             L=mid+1;
    49         }
    50     }
    51     return result;
    52 }
    53 int solve(){
    54     init();
    55     int answer=n;
    56     for(int i=0;i<n;i++){
    57         int last=bs(i);
    58         if(last==-1) break;
    59         answer=min(answer,last-i+1);
    60     }
    61     return answer;
    62 }
    63 int main(){
    64     #ifdef txtout
    65     freopen("in.txt","r",stdin);
    66     freopen("out.txt","w",stdout);
    67     #endif // txtout
    68     while(~scanf("%d%s",&n,a)){
    69         printf("%d
    ",solve());
    70     }
    71     return 0;
    72 }
    View Code

     赛后考虑单调队列, 双指针实现,比上述方法快10倍,  开始 起点和终点都在 0,  如果当前种类少于总的种类,则序列一定要变长,  终点往后走一个.  

    如果当前种类等于总共的种类, 更新答案.  此时说明该起点的最近的终点已经找到,  起点往后走一个.  那么下一个起点必定少了一个字符,  因此种类数只会比之前差,或相等, 因此终点只可能往后走,或是停留原位,不可能往前走,

    那么最终起点和终点都是on的往后走, 复杂度on.

     1 //#define txtout
     2 //#define debug
     3 #include<bits/stdc++.h>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 typedef long long LL;
     7 const double pi=acos(-1.0);
     8 const double eps=1e-8;
     9 const int inf=0x3f3f3f3f;
    10 const int M=1e5+10;
    11 int n;
    12 char a[M];
    13 int sum[64];
    14 int toint(char c){
    15     if(c>='a'&&c<='z') return c-'a';
    16     return c-'A'+26;
    17 }
    18 int solve(){
    19     mt(sum,0);
    20     int total=0;
    21     for(int i=0;i<n;i++){
    22         int id=toint(a[i]);
    23         sum[id]++;
    24         if(sum[id]==1) total++;
    25     }
    26     int result=n;
    27     mt(sum,0);
    28     int s=0,t=0,nowTotal=1;
    29     sum[toint(a[0])]++;
    30     while(true){
    31         if(s>=n) break;
    32         if(total==nowTotal){
    33             result=min(result,t-s+1);
    34             int id=toint(a[s]);
    35             sum[id]--;
    36             if(sum[id]==0) nowTotal--;
    37             if(s+1<=t){
    38                 s++;
    39                 continue;
    40             }
    41             s=t+1;
    42             t=s;
    43             continue;
    44         }
    45         if(t+1>=n) break;
    46         t++;
    47         int id=toint(a[t]);
    48         sum[id]++;
    49         if(sum[id]==1) nowTotal++;
    50     }
    51     return result;
    52 }
    53 int main(){
    54     #ifdef txtout
    55     freopen("in.txt","r",stdin);
    56     freopen("out.txt","w",stdout);
    57     #endif // txtout
    58     while(~scanf("%d%s",&n,a)){
    59         printf("%d
    ",solve());
    60     }
    61     return 0;
    62 }
    View Code

    D

     1 //#define txtout
     2 //#define debug
     3 #include<bits/stdc++.h>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 typedef long long LL;
     7 const double pi=acos(-1.0);
     8 const double eps=1e-8;
     9 const int inf=0x3f3f3f3f;
    10 const int M=1e5+10;
    11 int n,l,v1,v2,k;
    12 
    13 bool judge(double cut_time,double len,int m){
    14     #ifdef debug
    15     printf("cut_time=%.3f   len=%.3f   m=%d
    ",cut_time,len,m);
    16     #endif // debug
    17     if(m==0) return true;
    18 //    if(len<eps) return true;
    19     if(v2*cut_time<len) return false;
    20     double t1=(len-v2*cut_time)/(v1-v2);
    21     double t2=cut_time-t1;
    22     double left=len-v1*t2;
    23     #ifdef debug
    24     printf("t1 = %.3f   t2 = %.3f    left = %.3f
    ",t1,t2,left);
    25     #endif // debug
    26     if(left<eps) return true;
    27     double carleft=len-v2*t2;
    28     double meettime=(left-carleft)/(v1+v2);
    29     left-=v1*meettime;
    30     if(left<eps) return true;
    31     return judge(t1-meettime,left,m-1);
    32 }
    33 double solve(){
    34     int m=n/k;
    35     if(n%k) m++;
    36     double L=0,R=l*1.0/v1;
    37     double answer=R;
    38     int step=100;
    39     while(step--){
    40         double mid=(L+R)*0.5;
    41         #ifdef debug
    42         printf("judge
    ");
    43         #endif // debug
    44         if(judge(mid,l,m)){
    45             answer=mid;
    46             R=mid;
    47         }
    48         else{
    49             L=mid;
    50         }
    51     }
    52     return answer;
    53 }
    54 int main(){
    55     #ifdef txtout
    56     freopen("in.txt","r",stdin);
    57     freopen("out.txt","w",stdout);
    58     #endif // txtout
    59     while(~scanf("%d%d%d%d%d",&n,&l,&v1,&v2,&k)){
    60         printf("%.10f
    ",solve());
    61     }
    62     return 0;
    63 }
    View Code

    E  赛后过的,记录一下,其实不难。题意给一个树,其中有2*m个节点是学校。现在要把这些学校两两一组配对,每一对有距离,目标使得m个距离的和最大。

    解法:宏观的来看。遍历每一条边,它能经过的次数是左右两边学校个数的小值。 通过dfs处理以u为根的子树的学校个数。 基于贪心的理论,即一条边左右两边都有点的话,会尽可能的让他们配对,那么配对数就是min(left,right)。也就是不考虑具体是哪两个匹配到一起,只要左右两边有点,就会尽可能的去匹配。

     1 //#define debug
     2 
     3 #include<bits/stdc++.h>
     4 using namespace std;
     5 typedef long long LL;
     6 const int M=2e5+10;
     7 struct E{
     8     int u,v;
     9 }e[M];
    10 vector<int> g[M];
    11 int x[M];
    12 int sum[M];
    13 bool is[M];
    14 int n,m;
    15 void init(){
    16     for(int i=1;i<=n;i++){
    17         is[i]=false;
    18         g[i].clear();
    19     }
    20     for(int i=0;i<m;i++){
    21         is[x[i]]=true;
    22     }
    23     for(int i=0;i<n-1;i++){
    24         g[e[i].u].push_back(e[i].v);
    25         g[e[i].v].push_back(e[i].u);
    26     }
    27 }
    28 void dfs_sum(int u,int fa){
    29     sum[u]=is[u];
    30     for(int i=0;i<g[u].size();i++){
    31         int v=g[u][i];
    32         if(v==fa) continue;
    33         dfs_sum(v,u);
    34         sum[u]+=sum[v];
    35     }
    36 }
    37 LL answer;
    38 void dfs(int u,int fa){
    39     for(int i=0;i<g[u].size();i++){
    40         int v=g[u][i];
    41         if(v==fa) continue;
    42         int son=sum[v];
    43         int other=m-sum[v];
    44         if(son<=other){
    45             answer+=son;
    46         }
    47         else{
    48             answer+=other;
    49         }
    50         dfs(v,u);
    51     }
    52 }
    53 LL solve(){
    54     init();
    55     dfs_sum(1,-1);
    56 
    57     #ifdef debug
    58     for(int i=1;i<=n;i++){
    59         printf("%d ",sum[i]);
    60     }
    61     puts("");
    62     #endif
    63 
    64     answer=0;
    65     dfs(1,-1);
    66     return answer;
    67 }
    68 int main(){
    69     while(~scanf("%d%d",&n,&m)){
    70         m<<=1;
    71         for(int i=0;i<m;i++){
    72             scanf("%d",&x[i]);
    73         }
    74         for(int i=0;i<n-1;i++){
    75             scanf("%d%d",&e[i].u,&e[i].v);
    76         }
    77         printf("%I64d
    ",solve());
    78     }
    79     return 0;
    80 }
    View Code

    F 赛后研究好几天也没过,后看了别人的思想 ,实现了好几天,终于过了.  题意给一个无向图, 删去小于等于2条边,使得st两点不连通 ,删去边 有花费 ,问总花费最小的方案.

    解法:  本来不通 0.   随便找一条 S 到T 路径,  必须删去路径上的一条边, 枚举 删去哪条 ,因为路径的边数只有n-1条.  删去边后,  判断, 如果不通了 ,  那么删这条边是一种方案,  如果还通,  做tarjan缩点, 

    当ST在一个连通分量内, 因为我们只剩一条可以删, 因此肯定无解 ,   不在一个连通分量时 ,  我们还是随便找一条 S到T的路径, 判断 路径上是否有桥, 有则可以通过删他达到目的.

    枚举第一条边n ,  tarjan m,  n*m的复杂度,  可能有更快的方法?

      1 //#define txtout
      2 //#define debug
      3 #include<bits/stdc++.h>
      4 #define mt(a,b) memset(a,b,sizeof(a))
      5 using namespace std;
      6 typedef long long LL;
      7 const double pi=acos(-1.0);
      8 const double eps=1e-8;
      9 const int inf=0x3f3f3f3f;
     10 const int M=1e5+10;
     11 int n,m,s,t;
     12 struct E {
     13     int u,v,w;
     14 } e[M];
     15 struct G {
     16     struct E {
     17         int v,w,id,next;
     18     } e[M];
     19     int le,head[M];
     20     void init(int n) {
     21         le=0;
     22         for(int i=0; i<=n; i++) head[i]=-1;
     23     }
     24     void add(int u,int v,int w,int id) {
     25         e[le].v=v;
     26         e[le].w=w;
     27         e[le].id=id;
     28         e[le].next=head[u];
     29         head[u]=le++;
     30     }
     31 } g;
     32 struct A {
     33     int sum;
     34     vector<int> id;
     35     void init() {
     36         sum=-1;
     37         id.clear();
     38     }
     39     void update(int tsum,int id1,int id2) {
     40         if(sum==-1||tsum<sum) {
     41             sum=tsum;
     42             id.clear();
     43             if(~id1) id.push_back(id1);
     44             if(~id2) id.push_back(id2);
     45         }
     46     }
     47 } answer;
     48 class Tarjan_U { ///����ͼ��ͨ�������� O(V+E)
     49     typedef int typec; ///��Ȩ������
     50     static const int ME=1e5+10; ///�ߵĸ���
     51     static const int MV=1e3+10; ///��ĸ���
     52     int n,Bcnt,Index,num[MV],dfn[MV],low[MV],belong[MV];
     53     stack<int> s;
     54     void addqiao(int u,int v,typec w) {
     55         now.u=u;
     56         now.v=v;
     57         now.w=w;
     58         qiao.push_back(now);
     59     }
     60     void tarjan(int u) {
     61         s.push(u);
     62         dfn[u]=low[u]=++Index;
     63         int v;
     64         for(int i=g.head[u]; ~i; i=g.e[i].next) {
     65             if(g.e[i].vis) continue;
     66             g.e[i].vis=g.e[i^1].vis=true;
     67             v=g.e[i].v;
     68             if (!dfn[v]) {
     69                 tarjan(v);
     70                 low[u]=min(low[u],low[v]);
     71                 if(dfn[u]<low[v]){
     72                     addqiao(u,v,g.e[i].w);
     73                     isbridge[g.e[i].id]=true;
     74                 }
     75                 continue;
     76             }
     77             low[u]=min(low[u],dfn[v]);
     78         }
     79         if(dfn[u]!=low[u]) return ;
     80         Bcnt++;
     81         do {
     82             v=s.top();
     83             s.pop();
     84             belong[v]=Bcnt;
     85             num[Bcnt]++;
     86         } while(v!=u);
     87     }
     88     struct G {
     89         struct E {
     90             int id;
     91             int v,next;
     92             bool vis;
     93             typec w;
     94         } e[ME];
     95         int le,head[MV];
     96         void init(int n) {
     97             le=0;
     98             for(int i=0; i<=n; i++) head[i]=-1;
     99         }
    100         void add(int u,int v,typec w,int id) {
    101             e[le].vis=false;
    102             e[le].v=v;
    103             e[le].w=w;
    104             e[le].id=id;
    105             e[le].next=head[u];
    106             head[u]=le++;
    107         }
    108     } g;
    109     struct Q {
    110         int u,v;
    111         typec w;
    112     } now;
    113     vector<Q> qiao;
    114     bool isbridge[ME];
    115 public:
    116     bool is_bridge(int id){
    117         return isbridge[id];
    118     }
    119     void init(int tn) { ///������������±� 1 ��ʼ
    120         n=tn;
    121         g.init(n);
    122     }
    123     void add(int u,int v,typec w,int id) {
    124         g.add(u,v,w,id);
    125         g.add(v,u,w,id);
    126     }
    127     void solve() {
    128         Index=Bcnt=0;
    129         for(int i=1; i<=n; i++) {
    130             num[i]=dfn[i]=low[i]=0;
    131         }
    132         for(int i=0;i<m;i++){
    133 
    134             isbridge[i]=false;
    135         }
    136         qiao.clear();
    137         while(!s.empty()) s.pop();
    138         for(int i=1; i<=n; i++) {
    139             if(!dfn[i]) {
    140                 tarjan(i);
    141             }
    142         }
    143     }
    144     int getbcnt() { ///��ͨ�����ĸ���
    145         return Bcnt;
    146     }
    147     int getbelong(int id) { ///�����ĸ������������±� 1 ��ʼ
    148         return belong[id];
    149     }
    150     int getnum(int id) { ///ij�������ĵ�ĸ���
    151         return num[id];
    152     }
    153 } tarjan;
    154 bool tabu[M];
    155 int pre[M];
    156 vector<int> EID,EID2;
    157 bool dfs(int u,int deleteID) {
    158     tabu[u]=true;
    159     if(u==t) return true;
    160     for(int i=g.head[u]; ~i; i=g.e[i].next) {
    161         int id=g.e[i].id;
    162         if(id==deleteID) continue;
    163         int v=g.e[i].v;
    164         if(tabu[v]) continue;
    165         pre[v]=u;
    166         bool flag=dfs(v,deleteID);
    167         if(flag) return true;
    168     }
    169     return false;
    170 }
    171 bool check_c(int deleteID) {
    172     for(int i=1; i<=n; i++) {
    173         tabu[i]=false;
    174     }
    175     return dfs(s,deleteID);
    176 }
    177 void get_edge(vector<int> &a,int deleteID) {
    178     a.clear();
    179     int u=t;
    180     while(u!=s) {
    181         for(int i=g.head[u]; ~i; i=g.e[i].next) {
    182             int id=g.e[i].id;
    183             if(id==deleteID) continue;
    184             int v=g.e[i].v;
    185             if(v!=pre[u]) continue;
    186             a.push_back(g.e[i].id);
    187             u=v;
    188             break;
    189         }
    190     }
    191 }
    192 void Delete(int deleteID) {
    193     bool flag=check_c(deleteID);
    194     if(!flag) {
    195         answer.update(e[deleteID].w,deleteID,-1);
    196         return ;
    197     }
    198     tarjan.init(n);
    199     for(int i=0;i<m;i++){
    200         if(i==deleteID) continue;
    201         tarjan.add(e[i].u,e[i].v,e[i].w,i);
    202     }
    203     tarjan.solve();
    204     if(tarjan.getbelong(s)==tarjan.getbelong(t)) return ;
    205     get_edge(EID2,deleteID);
    206     for(int i=0;i<EID2.size();i++){
    207         int id=EID2[i];
    208         #ifdef debug
    209         printf("id2=%d
    ",id);
    210         #endif // debug
    211         if(!tarjan.is_bridge(id)) continue;
    212         answer.update(e[deleteID].w+e[id].w,deleteID,id);
    213     }
    214 }
    215 void solve() {
    216     answer.init();
    217     g.init(n);
    218     for(int i=0; i<m; i++) {
    219         g.add(e[i].u,e[i].v,e[i].w,i);
    220         g.add(e[i].v,e[i].u,e[i].w,i);
    221     }
    222     bool flag=check_c(-1);
    223     if(!flag) {
    224         answer.update(0,-1,-1);
    225         return ;
    226     }
    227     get_edge(EID,-1);
    228     for(int i=0; i<EID.size(); i++) {
    229         #ifdef debug
    230         printf("id=%d
    ",EID[i]);
    231         #endif // debug
    232         Delete(EID[i]);
    233     }
    234 }
    235 int main() {
    236 #ifdef txtout
    237     freopen("in.txt","r",stdin);
    238     freopen("out.txt","w",stdout);
    239 #endif // txtout
    240     while(~scanf("%d%d%d%d",&n,&m,&s,&t)) {
    241         for(int i=0; i<m; i++) {
    242             scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    243         }
    244         solve();
    245         int sum=answer.sum;
    246         printf("%d
    ",sum);
    247         if(sum==-1) continue;
    248         printf("%d
    ",answer.id.size());
    249         for(int i=0; i<answer.id.size(); i++) {
    250             printf("%d%c",answer.id[i]+1,i==answer.id.size()-1?'
    ':' ');
    251         }
    252     }
    253     return 0;
    254 }
    View Code

    end

  • 相关阅读:
    c# 生成随机时间
    HttpWebRequest.ReadWriteTimeout 属性
    如果分配给命令的连接位于本地挂起事务中,ExecuteNonQuery 要求命令拥有事务。命令的 Transaction 属性尚未初始化
    Host 'XXX' is not allowed to connect to this MySQL server 解决方案/如何开启MySQL的远程帐号
    C# winform 获取当前路径
    c# 操作符重载
    为何好男人总被坏女人搞定?【转】
    MySQL,SQLSERVER,ORACLE获取数据库表名及字段名
    病毒加壳技术与脱壳杀毒方法解析
    配置linux DNS
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/5698031.html
Copyright © 2011-2022 走看看