首页 > 其他分享 >Codeforces Round #287 (Div. 2) 解题报告 A.B.C.D.E

Codeforces Round #287 (Div. 2) 解题报告 A.B.C.D.E

时间:2023-04-13 23:39:14浏览次数:30  
标签:cnt const int LL Codeforces edge Div include Round


这次的CF挺水的,当时B题犯了一个很SB的错误,浪费了好多时间,所以D和E也没来得及看。sad,。。

A - Amr and Music

水题,从小的开始选。

代码如下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
const int mod=9901;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
struct node {
        int x, n;
} fei[400];
int cmp(node f1, node f2)
{
        return f1.x<f2.x;
}
int main()
{
        int n, m, i, sum=0, j, pos;
        scanf("%d%d",&n,&m);
        for(i=0; i<n; i++) {
                scanf("%d",&fei[i].x);
                fei[i].n=i+1;
        }
        sort(fei,fei+n,cmp);
        pos=n-1;
        for(i=0; i<n; i++) {
                if(sum+fei[i].x>m) {
                        pos=i-1;
                        break;
                } else {
                        sum+=fei[i].x;
                }
        }
        printf("%d\n",pos+1);
        for(j=0; j<=pos; j++) {
                printf("%d ",fei[j].n);
        }
        return 0;
}

B - Amr and Pins

只要距离小于2*r,那么肯定能找到一个点可以正好将圆心移到目标点。所以只要看距离是2*r的多少倍就可以了。该死的精度。。取10^-9就挂了。。换成别的都过了。。无语。。

代码如下:


#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
const int mod=9901;
const int INF=0x3f3f3f3f;
const double eqs=1e-11;
int main()
{
        LL r, x1, y1, x2, y2;
        LL a;
        double d, c;
        while(scanf("%I64d%I64d%I64d%I64d%I64d",&r,&x1,&y1,&x2,&y2)!=EOF){
                        r*=2;
                d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
                c=d/r;
                a=(LL)c;
                if(c==a){
                        printf("%I64d\n",a);
                }
                else
                        printf("%I64d\n",a+1);
        }
        return 0;
}

C - Guess Your Way Out!

我的做法是先建树,记录到目标点的最短路径,然后再从根节点出发开始走,如果下一步偏离了路径,那么就加上下一步的所有子树节点的个数。(因为它肯定会遍历完所有子树然后返回)

代码如下:


#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
const int mod=9901;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
LL ans, c, num[100], cnt, p[100], H;
void update(LL n, LL l, LL r, LL rt)
{
        num[cnt++]=rt;
        if(l==r) return ;
        LL mid=l+r>>1;
        if(n<=mid) update(n,lson);
        else update(n,rson);
}
void dfs(int f, int h, LL l, LL r, LL rt)
{
        if(l==r) return ;
        LL next;
        if(f==-1) next=rt<<1;
        else next=rt<<1|1;
        if(next!=num[h+1]) {
                ans+=p[H-h-1];
                f=-f;
        }
        c>>=1;
        LL mid=l+r>>1;
        if(f==-1) {
                dfs(-f,h+1,lson);
        } else {
                dfs(-f,h+1,rson);
        }
}
void init()
{
        p[0]=1;
        for(int i=1; i<=60; i++) {
                p[i]=p[i-1]+((LL)1<<i);
                //printf("%I64d\n",p[i]);
        }
}
int main()
{
        LL n, i;
        while(scanf("%I64d%I64d",&H,&n)!=EOF) {
                ans=0;
                c=(LL)1<<H;
                cnt=0;
                init();
                update(n-1,0,c-1,1);
                /*for(i=0;i<cnt;i++){
                        printf("%I64d\n",num[i]);
                }*/
                dfs(-1,0,0,c-1,1);
                printf("%I64d\n",ans+H);
        }
        return 0;
}


D - The Maths Lecture


水题啊。。。普通的数位DP而已,用dp[i][j][k]记录第i位(从低位开始数),模为j时,k记录是否已经存在模为0的后缀的状态时的个数。因为要算后缀,所以应该从低位向高位开始搜。

代码如下:


#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
int mod, k, n;
const int INF=0x3f3f3f3f;
const double eqs=1e-6;
LL dp[1002][101][3], mo[1002];
LL dfs(int cnt, int mods, int in, int zero)
{
        if(cnt==-1) return in;
        if(zero&&dp[cnt][mods][in]!=-1) return dp[cnt][mods][in];
        int l=(cnt==0), i, m, z;
        LL ans=0;
        for(i=l;i<=9;i++){
                m=(mods+i*mo[n-cnt])%k;
                if(i||zero) z=1;
                else z=0;
                ans+=dfs(cnt-1,m,in||(m==0&&z),z);
        }
        ans%=mod;
        if(zero)    {
                        dp[cnt][mods][in]=ans;
        }
        return ans;
}
void init()
{
        int i;
        mo[1]=1%k;
        for(i=2;i<=1000;i++){
                mo[i]=(mo[i-1]*10)%k;
        }
}
int main()
{
        memset(dp,-1,sizeof(dp));
        scanf("%d%d%d",&n,&k,&mod);
        init();
        printf("%I64d\n",dfs(n-1,0,0,0));
        return 0;
}


E - Breaking Good


还是水题。。求一次最短路,将距离标记成一个比较大的数,然后将花费标记成1,这样就能找到了最短而且花费最短的路径了。然后再根据状态标记找到需要改动的路径即可。

代码如下:


#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
int mod, k, n;
const int INF=0x3f3f3f3f;
const double eqs=1e-6;
int head[110000], cnt, vis[110000], dd[110000], pre[110000], c[110000];
struct node
{
        int u, v, w, next, f, s;
}edge[210000];
void add(int u, int v, int w, int f)
{
        edge[cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].f=f;
        edge[cnt].next=head[u];
        head[u]=cnt++;
}
void spfa()
{
        queue<int>q;
        memset(vis,0,sizeof(vis));
        q.push(1);
        dd[1]=0;
        while(!q.empty()){
                int u=q.front();
                q.pop();
                vis[u]=0;
                for(int i=head[u];i!=-1;i=edge[i].next){
                        int v=edge[i].v;
                        if(dd[v]>dd[u]+edge[i].w){
                                dd[v]=dd[u]+edge[i].w;
                                pre[v]=u;
                                if(!vis[v]){
                                        vis[v]=1;
                                        q.push(v);
                                }
                        }
                }
        }
}
void init()
{
        memset(head,-1,sizeof(head));
        cnt=0;
        memset(dd,INF,sizeof(dd));
        memset(pre,-1,sizeof(pre));
}
int main()
{
        int n, m, i, u, v, w, j, sum=0, cnt1=0;
        scanf("%d%d",&n,&m);
        init();
        while(m--){
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,10000+1-w, w);
                add(v,u,10000+1-w, w);
        }
        spfa();
        for(i=n;i!=-1;i=pre[i]){
                c[cnt1++]=i;
        }
        for(i=1;i<=n;i++){
                for(j=head[i];j!=-1;j=edge[j].next){
                        edge[j].s=0;
                }
        }
        for(i=cnt1-1;i>=1;i--){
                u=c[i];
                for(j=head[u];j!=-1;j=edge[j].next){
                        int v=edge[j].v;
                        if(v==c[i-1]){
                                edge[j].s=1;
                                edge[j^1].s=1;
                                //printf("%d %d %d\n",u,v,edge[j].w);
                        }
                }
        }
        for(i=1;i<=n;i++){
                for(j=head[i];j!=-1;j=edge[j].next){
                        if(edge[j].s+edge[j].f==1){
                                edge[j^1].f=1-edge[j^1].f;
                                //printf("%d %d %d %d\n",i,edge[j].v,edge[j].s,edge[j].w);
                                sum++;
                        }
                }
        }
        printf("%d\n",sum);
        for(i=1;i<=n;i++){
                for(j=head[i];j!=-1;j=edge[j].next){
                        if(edge[j].s+edge[j].f==1){
                                printf("%d %d %d\n",i,edge[j].v,edge[j].s);
                        }
                }
        }
        return 0;
}



标签:cnt,const,int,LL,Codeforces,edge,Div,include,Round
From: https://blog.51cto.com/u_16070138/6188695

相关文章

  • Codeforces Round #286 (Div. 2) C题 Mr. Kitayuta, the Treasure Hunter (DFS+记忆化D
    题目地址:http://codeforces.com/contest/505/problem/C从d点开始,每个点都有三个方向,形成了一棵树,那么就从跟结点开始进行dfs查找,dp数组记录当前的点和长度,当这两个条件相同的时候,显然,后面的子树是完全相同的,于是用记忆化来优化。代码如下:#include<iostream>#include<string.h>#......
  • codeforces #185 A Plant(矩阵快速幂+递推)
    题目地址:http://codeforces.com/problemset/problem/185/A通过这个题终于找回了点找递推公式的信心。。TAT。。不过真心感觉CF的题目质量都真不错。。。首先,第n个图形的上方,左下方,右下方的三个大三角形是跟第n-1个是一模一样的,所以是3*f(n-1)。然后只剩下中间一个倒着的大三角形了,......
  • Codeforces Round #286 (Div. 1) B. Mr. Kitayuta's Technology (强连通分量)
    题目地址:http://codeforces.com/contest/506/problem/B先用强连通判环,然后转化成无向图,找无向图连通块,若一个有n个点的块内有强连通环,那么需要n条边,即正好首尾相连形成一条环,那么有了这个环之后,在这个块内的所有要求都能实现。如果没有强连通环,那么就是一棵树,那么只需要n-1条边即......
  • Codeforces Round #307 (Div. 2) E. GukiZ and GukiZiana (分块)
    题目地址:http://codeforces.com/contest/551/problem/E将n平均分成sqrt(n)块,对每一块从小到大排序,并设置一个整体偏移量。修改操作:l~r区间内,对两端的块进行暴力处理,对中间的整体的块用整体偏移量标记增加了多少。时间复杂度:O(2*sqrt(n)+n/sqrt(n)).查询操作:对每一块二分,查找......
  • Codeforces Round #303 (Div. 2) E. Paths and Trees (最短路+变形最小生成树)
    题目地址:E.PathsandTrees模拟了一场CF,这场实在太水了。。边玩边做的。。最后半分钟交了一发E题。。不幸AK绝杀失败。。。。首先的思路肯定是先求最短路,把可能为最短路的边挑出来,然后第二步我本来写的是直接用无向图的最小生成树,于是绝杀失败。。。后来才发现这样是不行的。......
  • Codeforces Round #316 (Div. 2) D. Tree Requests (DFS序)
    题目地址:http://codeforces.com/contest/570/problem/D比赛的时候实在没想到DFS序,。。想到DFS序后,分别存起每个深度的所有节点的DFS序,处理出前缀异或和,然后二分找到两个端点,再异或一下,就求出了所求区间的异或和,由于偶数次的都被异或掉了,所以判断下奇数次数是否大于1即可。代码......
  • Codeforces Round #284 (Div. 1) C. Array and Operations (最大流)
    题目地址:http://codeforces.com/contest/498/problem/C分别分解出每个数字的质因子,然后第奇数个数字的质因子在左边集合,偶数个数字的质因子在右边集合,建立源点和汇点,然后根据每个数字含有的质因子的个数建边,跑一遍最大流即可。代码如下:#include<iostream>#include<string.h>......
  • Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome (DP+字典树)
    题目地址:传送门先用dp求出所有的符合要求的半回文串,标记出来。然后构造字典树。然后再dfs一遍求出所有节点的子树和,最后搜一遍就能找出第k个来了。代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib......
  • Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)
    题目地址:codeforces#pi(DIV2)E题目很水。。就是先求两边最短路,然后把可能为最短路的边挑出来,然后判断是否yes只需要转化成无向图跑一遍tarjan,找出割边,割边就是yes,然后剩下的边就让它的值为最短路-1就行了,如果-1后变成了非正数,就是no.但是!!!居然卡spfa!!那是不是说cf以后就不......
  • Codeforces Round #305 (Div. 1) A.B.C 解题报告
    A.MikeandFrog枚举。先是找循环,然后很容易得出一个两元一次方程,然后可以发现解也是有循环节的,所以最小的那个肯定出现在一定范围内,否则就后面也不可能出现。假设两个变量为x,y,系数分别为z1,z2。很显然,两者的最小公倍数便是一个周期,所以如果枚举x的话,只需要枚举到z2就可......