• 【自家测试】2018-5-9


    翡翠的排挤原理
    【前言】
    一些以宝石命名的书籍,拥有神奇的能力,乃魔法之书.
    魔法之书会自动挑选附近有意志讲述故事的人作为原著的表演者,在现实中
    演绎故事,只有当故事迎来结尾,魔法之书才会合上.
    时至今日,故事仍在不停地打开......
    【问题描述】
    少年注意到了一个少女.
    少女总是孤身一人,受人冷落.不知从何时开始,不幸的魔法使,人们这样称呼
    她.
    少女总是在少年面前遭遇不幸:走路差点被车撞;被不知名的罪犯在桌子上乱
    刻;下楼梯被看不见的凶手推下楼......
    少年开始帮少女调查凶手,却找不到任何线索.在寻找的途中,少年和少女相恋
    了,少女不再孤身一人.
    调查仍在继续.少年又发现了一样少女被破坏的东西,那是一张纸,纸上似乎曾
    写着N 个数,而现在,每个数都被破坏得只剩下了一个数字.
    这曾是一个非负整数的等差数列,公差也非负.这N 个数字分别是等差数列每
    个数字的其中一位,并且都是同一位.在序列旁,犯罪者如此宣称到.
    看着清秀的字迹,少年若有所思.
    少年决定先将故事还原,再揭开故事的谜底.
    让一切都重新开始吧.
    (注:一个数字的位指的是这个数字从低到高数上来的数字,且位数不足用0补
    齐.如102的第一位是2,第二位是0,第三位是1,第四位是0.)
    【输入格式】
    从文件 emerald.in 中读入数据。
    一行一个长度为N 的字符串描述这个剩余的这个串.

    【输出格式】
    输出到文件 emerald.out 中。
    一行输出该等差数列的首项.如果有多个首项满足条件,则输出最小的首项.如
    果没有首项,就输出−1.
    【样例输入1】
    6925814703
    【样例输出1】
    6
    【样例解释】
    取A i = 6 + 3 * i,保留该等差数列的第一位即为答案.
    【数据规模】
    对于10%的数据:N ≤ 10.
    对于30%的数据:N ≤ 100.
    对于50%的数据:N ≤ 1000
    对于70%的数据:N ≤ 7000
    对于100%的数据:N ≤ 10000.

    题解

     1 //Achen
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<queue>
     9 #include<cmath>
    10 #include<set>
    11 #include<map>
    12 #define eps 1e-9
    13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    15 const int N=10007;
    16 typedef long long LL; 
    17 typedef double db;
    18 using namespace std;
    19 int n,q[N],p[N];
    20 char s[N];
    21 db l,r;
    22 
    23 template<typename T> void read(T &x) {
    24     char ch=getchar(); x=0; T f=1;
    25     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    26     if(ch=='-') f=-1,ch=getchar();
    27     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    28 }
    29 
    30 #define DEBUG
    31 int main() {
    32 #ifdef DEBUG
    33     freopen("emerald.in","r",stdin);
    34     freopen("emerald.out","w",stdout);
    35 #endif
    36     scanf("%s",s);
    37     n=strlen(s);
    38     int tp=s[1]-s[0]<0?s[1]-s[0]+10:s[1]-s[0];
    39     int mx=tp,mi=tp;
    40     For(i,1,n-1) {
    41         int x1=s[i]-'0',x2=s[i-1]-'0';
    42         int tp=x1>=x2?x1-x2:x1+10-x2;
    43         mx=max(mx,tp),mi=min(mi,tp);
    44     }
    45     if(mx-mi>1) puts("-1");
    46     else if(mx==mi) printf("%d
    ",s[0]-'0');
    47     else {
    48         q[1]=s[0]-'0';
    49         For(i,2,n) {
    50             q[i]=q[i-1]+mi+(s[i-1]-'0'==(s[i-2]-'0'+mi+1)%10); 
    51             p[i]=1-i;
    52         }
    53         r=1e9,l=0;
    54         For(i,1,n) For(j,1,n) if(i!=j) {
    55             if(p[i]-p[j]>0) {
    56                 r=min(r,(db)(q[j]+1-q[i])/(db)(p[i]-p[j]));
    57             }
    58             else {
    59                 l=max(l,(db)(q[j]+1-q[i])/(db)(p[i]-p[j]));
    60             }
    61         }
    62         r-=eps; l+=eps;
    63         int k=0,d,bs=1;
    64         for(;;k++) {
    65             if((int)l!=(int)r||(l<=0&&r>=0)) {
    66                 d=(int)r; break;
    67             }
    68             bs*=10;
    69             l*=10;
    70             r*=10;
    71         }
    72         int ans=q[1]*bs+p[1]*d;
    73         For(i,1,n) 
    74             ans=max(ans,q[i]*bs+p[i]*d);
    75         printf("%d
    ",ans);
    76     } 
    77     return 0;
    78 }
    View Code

    蓝宝石的存在证明
    【问题描述】
    少年少女来到一座废弃的仓库寻找宝藏.一条早已被人遗忘的蓝宝石项链重
    见天日,不幸发生了.
    周围的人逐渐忘记少女是谁,只有少年仍旧记得,爱着少女.
    决不会忘记,少年历下海誓山盟.终于,少年也忘记了,自己深爱着的少女.
    少女并没有放弃,继续奋斗着.终于在那个仓库里,少女找到了破解这个禁锢的
    希望.
    那是一块石板,石板上曾有N 颗蓝宝石,M 条纹路连接着M 对宝石.完整的石板
    具有强大的魔力,能够帮助许愿人冲破一切的束缚.
    由于时间的侵蚀,石板上的蓝宝石早已不见踪影,现在的石板只是一些空的底
    座和纹路.
    同样,这些纹路也拥有特殊的能力,当一条纹路连接的两侧都没有蓝宝石时,许
    愿者可以让这两个底座都出现一个蓝宝石;同样的,如果两侧都有宝石,那么许愿者
    可以让它们都消失.
    许愿者不能拿走宝石,否则会触怒石板.当每个位置上都有蓝宝石时,奇迹就会
    发生.
    少女最终完成了任务,世界重新记起了这个可怜的少女,可喜可贺可喜可贺.
    世间流传少女的故事,石板谜题也同样作为经典问题留存至今.你对这个问题
    非常感兴趣,并希望能够用最少的步数解决这个谜题.
    (注:做题前请仔细阅读数据规模,以免不必要的麻烦.
    【输入格式】
    从文件 sapphire.in 中读入数据。
    第一行两个正整数N, M ,其中N 为图的点数,M 为图的边数.
    接下来M 行,每行两个正整数x, y,描述一条边.
    【输出格式】
    输出到文件 sapphire.out 中。

    一行描述最少的步数.如果无解输出−1.
    【样例输入1】
    6 5
    1 2
    1 3
    1 4
    2 5
    2 6
    【样例输出1】
    5
    【数据规模】
    本题采用打包评测.
    Subtask1(10points):N ≤ 10.
    Subtask2(40points):N ≤ 100000且M = N − 1.
    Subtask3(50points):N ≤ 100000且N − 1 ≤ M ≤ N .
    所有数据均保证任意两个底座相互连通,且M ≤ N .

    考试的时候写的辣鸡dp什么细节都没有,没考虑不用额外边的情况,只考虑了奇环,并且还没有加上额外的代价,成功GG

    题解有个比较神的模型转换,二分图染色,原题转换为每个黑点上有一个棋子,要用最少都步数使棋子都移动到白点上.即把黑点没有棋子,白点有棋子看做有宝石,黑点有棋子,白点没有棋子看做无宝石,讨论环的奇偶

    其实意思都差不多,我就直接用宝石都模型dp了.下面把有宝石的叫做非空点,没有的叫空点

    用f[x]表示x点还需要与多少个空点相连,也就是需要它的父亲成为空点然后与他进行操作多少次.若f[x]为负,则表示需要与多少个非空点相连,同理.

    每个点的初始f[x]为1,转移为每次减去它儿子的f值

    这样若根的f值为0即存在合法操作.操作数就是abs(f[x])之和.

    对于基环树,考虑多出的一条边带来的影响,显然是可以让这条边都两个点的f值同时加上一个数.

    我把这条边的一个点作为了根,其实应该是无所谓的。这样我们设这个数为x,每个点的f变为两维,f[i]=a[i]*x+b[i];

    如果环长为奇数,那么根的值f[rt]=2*x+b[rt],要使f[rt]=0,x有唯一解。

    如果环长为偶数,那么f[rt]=b[rt],若b为0,x有解,否则无解。

    有解时答案为abs(a[i]*x+b[i])之和,a[i]==0.1,-1,a=0时直接计算答案。

    把x看做数轴上一点,a=-1时答案为b[i]到x的距离,a=1时答案为-b[i]到x的距离,那么把这些b拿出来取中位数即可。

    注意的点就是

    1.要考虑环的奇偶

    2.非树边可能没用,应该设f[u]=x+1而不是f[u]=x

    3.最后的代价要加上非树边的代价x。

    4.数据有毒,存在自环,模型解释不通,强行理解为在自环上操作一次需要其他的地方两次操作才能变回来。那么特判一波,不需要这条边的情况算一次,再设这个点为2*x+1算一次。

      1 //Achen
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<vector>
      7 #include<cstdio>
      8 #include<queue>
      9 #include<cmath>
     10 #include<set>
     11 #include<map>
     12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     14 const int N=100007;
     15 typedef long long LL; 
     16 typedef double db;
     17 using namespace std;
     18 int n,m;
     19 
     20 template<typename T> void read(T &x) {
     21     char ch=getchar(); x=0; T f=1;
     22     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     23     if(ch=='-') f=-1,ch=getchar();
     24     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     25 }
     26 
     27 int ecnt,fir[N],nxt[N<<1],to[N<<1];
     28 void add(int u,int v) {
     29     nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
     30     nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
     31 }
     32 
     33 int tot;
     34 int dfs(int x,int fa) {
     35     int rs=1;
     36     for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
     37         rs-=dfs(to[i],x);
     38     }
     39     tot+=abs(rs);
     40     return rs;
     41 }
     42 
     43 struct pt {
     44     int a,b; // a*x+b;
     45     pt(){}
     46     pt(int a,int b):a(a),b(b){}
     47 }val[N];
     48 pt operator -(const pt &A,const pt &B) { return pt(A.a-B.a,A.b-B.b); }
     49 
     50 int fa[N],rt,spf;
     51 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }
     52 
     53 int v[N];
     54 void dfs2(int x,int fa) {
     55     if(x!=spf&&x!=rt) val[x]=pt(0,1);
     56     else { if(rt==spf) val[x]=pt(2,1); else val[x]=pt(1,1); }
     57     for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
     58         dfs2(to[i],x);    
     59         val[x]=val[x]-val[to[i]];
     60     }
     61     if(val[x].a>0) v[++tot]=-val[x].b;
     62     else if(val[x].a<0) v[++tot]=val[x].b;
     63 }
     64 
     65 #define DEBUG
     66 int main() {
     67 #ifdef DEBUG
     68     freopen("sapphire.in","r",stdin);
     69     freopen("sapphire.out","w",stdout);
     70 #endif
     71     read(n); read(m);
     72     if(m==n-1) {
     73         For(i,1,m) {
     74             int u,v;
     75             read(u); read(v);
     76             add(u,v);
     77         }
     78         int rs=dfs(1,0);
     79         if(rs==0) printf("%d
    ",tot);
     80         else puts("-1");
     81     }
     82     else {
     83         For(i,1,n) fa[i]=i;
     84         For(i,1,m) {
     85             int u,v;
     86             read(u); read(v);
     87             if(find(u)!=find(v)) {
     88                 add(u,v);
     89                 fa[find(u)]=find(v);
     90             }
     91             else rt=u,spf=v;
     92         }
     93         dfs2(rt,0);
     94         if(val[rt].a==0&&val[rt].b!=0) puts("-1");
     95         else {
     96             if(val[rt].a==0) {
     97                 sort(v+1,v+tot+1);
     98                 int x=v[tot/2+1];
     99                 int ans=abs(x);
    100                 For(i,1,n) 
    101                     ans+=abs(val[i].a*x+val[i].b);
    102                 printf("%d
    ",ans);
    103             }
    104             else {
    105                 if(spf==rt&&val[rt].b==-1) {
    106                     tot=0; dfs(rt,0);
    107                     printf("%d
    ",tot); return 0;
    108                 }
    109                 else if(abs(val[rt].b)%val[rt].a!=0) puts("-1");
    110                 else {
    111                     int x=-val[rt].b/val[rt].a;
    112                     tot=0;
    113                     For(i,1,n) 
    114                         tot+=abs(val[i].a*x+val[i].b);
    115                     tot+=abs(x);
    116                     printf("%d
    ",tot);
    117                 }
    118             }
    119         }
    120     }
    121     return 0;
    122 }
    View Code

    萤石的怠惰现象
    【问题描述】
    (由于一些不可描述的原因,故事被吃掉啦.)
    给 出 一 张 点 数 为N ,边 数 为M 的 无 向 图G = (V, E).求 有 多 少V ′ ⊆ V ,满
    足|V ′ | = k且对∀(u, v) ∈ E,满足u, v至少有一个不在V ′ 中,答案对M o取模.
    【输入格式】
    第一行四个整数N, M, k, M o.
    接下来M 行,每行两个整数u, v,描述一条边.
    【输出格式】
    一行输出答案对M o取模的值.
    【评分方式】
    本题为提交答案题.你可以从下发的文件中得到subset1.in到subset10.in这10个
    读入文件,并将答案输出到subset1.out到subset10.out这10个输出文件中.
    对于1到10号测试点,如果你通过了这个测试点,你将分别可以得到
    5, 6, 14, 8, 12, 11, 9, 13, 7, 15分.
    【如果测试你的输出】
    在终端中先切换到该试题的目录下(windows用户请使用cmd)
    cdsubset
    我们提供checker这个工具来测试你的输出文件是否正确。 使用这个工具的
    方法是,在终端中运行
    ./checker < case no >
    其中case no 是测试数据的编号。例如
    ./checker 3
    将测试subset3.out是否正确。 (windows用户请使用checker 3)

    在你调用这个程序后,checker将根据你给出的输出文件给出测试的结果。

     1.2点可以爆搜

     3.4点树dp,需要滚动数组,4要放着跑一会。

     5点是一个不完全的12*12的格子图,可以状压dp

    剩下的点没做了。

     老是喜欢把博客堆到一块写,一写就很久,有点累啊。。。

  • 相关阅读:
    [RxJS] defer() lazy evaluation
    [React] as component prop
    [Compose] Compose exercises
    MAC开发NDK非常的简单
    Android之zip包换肤(极力推荐)
    Android之获取sdcard卡的信息
    Android之Volley使用
    Android之与当前连接的wifi进行文件夹的浏览与传输
    android之获得当前连接wifi的名字
    android之截屏(包括截取scrollview与listview的)
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9024222.html
Copyright © 2020-2023  润新知