18.5.19 自测

1.魔术球问题弱化版(ball.c/.cpp/.pas)

题目描述

假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球。

(1)每次只能在某根柱子的最上面放球。

(2)在同一根柱子中,任何 2 个相邻球的编号之和为完全平方数。

试设计一个算法,计算出在 n 根柱子上最多能放多少个球。例如,在 4 根柱子上最多可放 11 个球。

对于给定的 n,计算在 n 根柱子上最多能放多少个球。

输入描述

第 1 行有 1 个正整数 n,表示柱子数。

输出描述

一行表示可以放的最大球数

4

样例输出。

样例输入

11

题目限制(为什么说弱化版就在这里)

N<=60,时限为3s;比起原题还有弱化在不用打出方案,方案太坑了

思路:模拟搞一下就好了。

#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
map<int,int>ma;
int n,ans;
int up[61];
int main(){
    freopen("ball.in","r",stdin);
    freopen("ball.out","w",stdout);
    for(int i=1;i<=360;i++)    ma[i*i]=1;
    scanf("%d",&n);
    up[1]=1;ans++;
    for(int i=2;i;i++){
        int flag=0;
        for(int j=1;j<=n;j++)
            if(ma[i+up[j]]==1||up[j]==0){
                up[j]=i;
                ans++;flag=1;
                break;
            }
        if(flag==0)    break;
    }
    cout<<ans;
}

2.征兵(conscription.c/.cpp/.pas)

一个国王,他拥有一个国家。最近他因为国库里钱太多了,闲着蛋疼要征集一只部队要保卫国家。他选定了N个女兵和M个男兵,但事实上每征集一个兵他就要花10000RMB,即使国库里钱再多也伤不起啊。他发现,某男兵和某女兵之间有某种关系(往正常方面想,一共R种关系),这种关系可以使KING少花一些钱就可以征集到兵,不过国王也知道,在征兵的时候,每一个兵只能使用一种关系来少花钱。这时国王向你求助,问他最少要花多少的钱。

读入(conscription.in)

第一行:T,一共T组数据。

接下来T组数据,

第一行包括N,M,R

接下来的R行 包括Xi,Yi,Vi 表示如果招了第Xi个女兵,再招第Yi个男兵能省Vi元(同样表示如果招了第Yi个男兵,再招第Xi个女兵能也省Vi元)

输出(conscription.out)

共T行,表示每组数据的最终花费是多少(因为国库里的钱只有2^31-1,所以保证最终花费在maxlongint范围内)

样例输入

2

5 5 8

4 3 6831

1 3 4583

0 0 6592

0 1 3063

3 3 4975

1 3 2049

4 2 2104

2 2 781

5 5 10

2 4 9820

3 2 6236

3 1 8864

2 4 8326

2 0 5156

2 0 1463

4 1 2439

0 4 4373

3 4 8889

2 4 3133

样例输出

71071

54223

数据范围

数据保证T<=5 ,m,n<=10000,r<=50000,Xi<=m,Yi<=n,Vi<=10000,结果<=2^31-1

【来源】

这道题我叫老师放在9018上了,原题是POJ 3723。

思路:跑一个最大生成树就可以了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 20010
using namespace std;
long long ans;
int t,n,m,r;
int fa[MAXN];
struct nond{
    int x,y,z,col;
}v[MAXN];
int cmp(nond a,nond b){ return a.z>b.z; }
int find(int x){ return fa[x]==x?fa[x]:fa[x]=find(fa[x]); }
int main(){
    freopen("conscription.in","r",stdin);
    freopen("conscription.out","w",stdout);
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&m,&r);
        ans=(n+m)*10000;
        for(int i=1;i<=n+m;i++)    fa[i]=i;
        for(int i=1;i<=r;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            x+=1;y+=1+n;v[i].x=x;
            v[i].y=y;v[i].z=z;
        }
        sort(v+1,v+1+r,cmp);
        for(int i=1;i<=r;i++){
            int dx=find(v[i].x),dy=find(v[i].y);
            if(dx==dy)    continue;
            fa[dx]=dy;ans-=v[i].z;
        }
        cout<<ans<<endl;ans=0;
        memset(v,0,sizeof(v));
    }
}
/*
2
5 5 8
4 3 6831
1 3 4583
0 0 6592
0 1 3063
3 3 4975
1 3 2049
4 2 2104
2 2 781

5 5 10
2 4 9820
3 2 6236
3 1 8864
2 4 8326
2 0 5156
2 0 1463
4 1 2439
0 4 4373
3 4 8889
2 4 3133
*/

3.坑爹的GPS(gpsduel.c/.cpp/.pas)

有一天,FJ买了一辆车,但是,他一手下载了两个GPS系统。好了现在麻烦的事情来了,GPS有一个功能大概大家也知道,如果FJ没有按照GPS内置地图的最短路走,GPS就会报错来骚扰你。现在FJ准备从他的农舍(在1这个点)开车到他的谷屋(n这个点)。FJ给了你两个GPS系统内置地图的信息,他想知道,他最少会听到多少次报错(如果FJ走的路同时不满足两个GPS,报错次数+2)

读入:第一行:n,k;n表示有FJ的谷屋在哪,同时保证GPS内置地图里的点没有超过n的点。K表示GPS内置地图里的路有多少条,如果两个点没有连接则表明这不是一条通路。

接下来k行,每行4个数X,Y,A,B分别表示从X到Y在第一个GPS地图里的距离是A,在第二个GPS地图里的是B。注意由于地形的其他因素GPS给出的边是有向边。

输出:一个值,表示FJ最少听到的报错次数。

样例输入:

5 7

3 4 7 1

1 3 2 20

1 4 17 18

4 5 25 3

1 2 10 1

3 5 4 14

2 4 6 5

样例输出:

1

解释

FJ选择的路线是1 2 4 5,但是GPS 1认为的最短路是1到3,所以报错一次,对于剩下的2 4 5,两个GPS都不会报错。

数据范围

N<=10000,至于路有多少条自己算吧。数据保证所有的距离都在2^31-1以内。

来源

USACO 2014年 全美公开赛银组第二题(各位轻虐银组题)

思路:先以a,b反向建图,跑两个spfa,然后求出走每条边的报错次数,然后在正向跑一个spfa。

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 10010
using namespace std;
int n,k,tot1,tot2,tot3;
queue<int>que1,que2,que3;
int vis1[MAXN],vis2[MAXN],vis3[MAXN];
long long dis1[MAXN],dis2[MAXN],dis3[MAXN];
int to1[MAXN],net1[MAXN],cap1[MAXN],head1[MAXN];
int to2[MAXN],net2[MAXN],cap2[MAXN],head2[MAXN];
int from[MAXN],to3[MAXN],net3[MAXN],cap3[MAXN],head3[MAXN];
void add1(int u,int v,int w){
    to1[++tot1]=v;cap1[tot1]=w;net1[tot1]=head1[u];head1[u]=tot1;
}
void add2(int u,int v,int w){
    to2[++tot2]=v;cap2[tot2]=w;net2[tot2]=head2[u];head2[u]=tot2;
}
void add3(int u,int v,int w){
    to3[++tot3]=v;from[tot3]=u;cap3[tot3]=w;net3[tot3]=head3[u];head3[u]=tot3;
}
void spfa1(int s){
    memset(vis1,0,sizeof(vis1));
    memset(dis1,0x7f,sizeof(dis1));
    while(!que1.empty())    que1.pop();
    que1.push(s);dis1[s]=0;vis1[s]=1;
    while(!que1.empty()){
        int now=que1.front();
        que1.pop();vis1[now]=0;
        for(int i=head1[now];i;i=net1[i])
            if(dis1[to1[i]]>dis1[now]+cap1[i]){
                dis1[to1[i]]=dis1[now]+cap1[i];
                if(!vis1[to1[i]]){
                    vis1[to1[i]]=1;
                    que1.push(to1[i]);
                }
            }
    }
}
void spfa2(int s){
    memset(vis2,0,sizeof(vis2));
    memset(dis2,0x7f,sizeof(dis2));
    while(!que2.empty())    que2.pop();
    que2.push(s);dis2[s]=0;vis2[s]=1;
    while(!que2.empty()){
        int now=que2.front();
        que2.pop();vis2[now]=0;
        for(int i=head2[now];i;i=net2[i])
            if(dis2[to2[i]]>dis2[now]+cap2[i]){
                dis2[to2[i]]=dis2[now]+cap2[i];
                if(!vis2[to2[i]]){
                    vis2[to2[i]]=1;
                    que2.push(to2[i]);
                }
            }
    }
}
void spfa3(int s){
    memset(vis3,0,sizeof(vis3));
    memset(dis3,0x7f,sizeof(dis3));
    while(!que3.empty())    que3.pop();
    que3.push(s);dis3[s]=0;vis3[s]=1;
    while(!que3.empty()){
        int now=que3.front();
        que3.pop();vis3[now]=0;
        for(int i=head3[now];i;i=net3[i])
            if(dis3[to3[i]]>dis3[now]+cap3[i]){
                dis3[to3[i]]=dis3[now]+cap3[i];
                if(!vis3[to3[i]]){
                    vis3[to3[i]]=1;
                    que3.push(to3[i]);
                }
            }
    }
}
int main(){
    freopen("gpsduel.in","r",stdin);
    freopen("gpsduel.out","w",stdout);
    scanf("%d%d",&n,&k);
    for(int i=1;i<=k;i++){
        int x,y,a,b;
        scanf("%d%d%d%d",&x,&y,&a,&b);
        add1(y,x,a);add2(y,x,b);
        add3(x,y,0);
    }
    spfa1(n);spfa2(n);
    for(int i=1;i<=tot3;i++){
        int u=to3[i],v=from[i];
        if(dis1[u]+cap1[i]>dis1[from[i]])    cap3[i]++;
        if(dis2[u]+cap2[i]>dis2[from[i]])    cap3[i]++;
    }
    spfa3(1);cout<<dis3[n];
}
/*
5 7
3 4 7 1
1 3 2 20
1 4 17 18
4 5 25 3
1 2 10 1
3 5 4 14
2 4 6 5
*/

原文地址:https://www.cnblogs.com/cangT-Tlan/p/9060509.html

时间: 2024-11-05 15:30:16

18.5.19 自测的相关文章

2017年1月18、19日活动记录

日程: 2017.1.18 1.运用多种方法制作水仙花数: (1)运用一重循环法制作水仙花数(do while) (2)运用三重循环法制作水仙花数(do while) (3)运用直到循环法制作水仙花数 2.直到循环1到100的和: (1)亿图软件制作流程图(2)利用VB制作直到循环1到100的和 3.十进制.二进制.十六进制之间的相互转化及其意义,列出了十进制.二进制.十六进制之间基数的转换表 4.利用亿图软件制作十进制转二进制流程图 5.利用辅助软件熟悉VB语句,并尝试了beep语句 6.利用

第十七节课:第18,19,23章,mariadb数据库、PXE无人值守安装系统和openldap目录服务。

第23章 (借鉴请改动) openldap数据的特点:1.短小.2.读取次数较多 上述说明: openLDAP服务端配置:     1.yum install -y openldap openldap-clients openldap-servers migrationtools  Loaded plugins: langpacks, product-id, subscription-manager //安装相关软件     2.生成秘钥文件并在/etc/hosts写入解析地址 slappass

18、19年渡一教育web前端高级工程师就业班视频教程下载

下载地址   百度网盘 [课程目录]├──第01节 课件及相关资料  |   ├──课件  |   |   ├──css3  |   |   |   ├──3d翻转.zip  97.77kb|   |   |   ├──css3 .pptx  2.51M|   |   |   ├──css3-Bootstrap.pptx  1.39M|   |   |   ├──css3-动画.pptx  3.36M|   |   |   ├──css3-媒体查询.pptx  806.76kb|   |   |

18寒假第三测

第一题:找LCA,两点之间的距离=他们各自到起点的距离 - 2*LCA到起点的距离 #include<bits/stdc++.h> using namespace std; const int maxn = 100015, P = 20; int head[2 * maxn],to[2 * maxn],last[2 *maxn],co[2 * maxn],dep[maxn], idx, anc[maxn][P+1],dis[maxn]; void dfs(int u,int from){ //

18寒假第六测

第一题:乘法修改的线段树 一定不能将change,modify分类讨论定两个标记,会有顺序影响 lazy标记一定要long long,又忘了... 代码和上一次差不多 第二题:离散暴力,也可以扫描线 离散时要将格子映射成点,不然会出现以下情况: 算横着的小矩形宽就是2,算黄色面积宽还是2,因为没有2让3去减 如果映射成点,就像这样,,放图比较好理解,就像扫描线,一个叶子节点存的是一个左闭右开的区间 也可以离散+扫描线,但还没写出来 #include <bits/stdc++.h> using

18寒假第五测

第一题 线段树 树状数组存差b[i] = a[i]-a[i-1],反正是单点查询,我为什么没想到...很傻的用线段树 #include<bits/stdc++.h> using namespace std; #define maxn 100005 #define ll long long int n, m, a[maxn]; struct SegmentTree{ struct node{ ll sum; int lazy; }; node Tree[maxn << 2]; #de

18.07.19(内置函数)

https://www.processon.com/mindmap/5b5071bee4b0f8477d8ae4c3 内置函数分为作用域相关(2).迭代器和生成器相关(3).其他(12).面向对象(9).基础类型相关(38).反射相关(4). 一.作用域相关 locals() 返回当前作用域中的名字 glogals() 返回全局作用域中的名字 二.迭代器和生成器相关: range() 生成数据 next() 迭代器向下执行一次,内部实际使用了__next__()方法返回迭代器的下一个项目 ite

18.8.19 考试总结

Gift[问题描述]人生赢家老王在网上认识了一个妹纸,然后妹纸的生日到了,为了表示自己的心意,他决定送她礼物. 可是她喜爱的东西特别多,然而他的钱数有限,因此他想知道当他花一定钱数后剩余钱数无法再购买任何一件剩余物品 (每种物品他最多买一个)时有多少种方案,两种方案不同,当且仅当两种方案中至少有一件品不 同,可是由于他忙着准备泡下一个妹纸(chi),因此麻烦聪明的你帮帮忙. [输入格式] 输入第一行 n 和m,n 表示妹纸喜欢的礼物数目,m 表示现有的钱数,第二行n 个数,表示n 个物品的价格.

18.10.16 队测

T1 : 求给定集合有多少个非空子集可以分割成两个集合,使得它们的和相等. 其中:\(n\leq20~,~a[i]\leq1e8\) 题目可以转化成:给每个数前添加一个系数\(p\in[-1,1]\),使得和为0的方案数. 由于\(n\)比较小,所以可以考虑爆搜.朴素的爆搜可以枚举每个数不选,第一个集合,第二个集合,复杂度\(O(3^n)\) . 然后发现根据套路,可以想到折半搜索\((meet~ in~ the ~middle)\) 先爆搜前十个的状态和\(sum\),然后爆搜后十个进行匹配,