A 服务器维护

题目大意:

  给出时间段[S,E],这段时间需要人维护服务器,给出n个小时间段[ai,bi],代表每个人会维护的时间段,每个人维护这段时间有一个花费,现在问题就是维护服务器[S,E]这段时间,需要最小花费是多少,就是用n个小时间段[ai,bi],覆盖满[S,E]这段时间并且所用的花费最少。

解题思路:

  解法一:最短路径,这是我一开始想到的用的算法,S到E需要使用最小花费,并且还给出每一小段的路程和花费,感觉就像最短路径裸题吖,但是这题问题在于如何建图,如果你使用常规方法建图是不可行的,因为最短路径是覆盖边,而这题给出的是需要覆盖点,假设[2,4] 我们需要覆盖点2,3,4三个点,而一般最短路径建图[2,4]是覆盖2->3,3->4两条边,我们就少一个覆盖的权,所以我们就把终点+1,[2,4]转换成[2,5],2->3,3->4,4->5,对应了2,3,4三个点,在建图时,假如给定区间[2,3] 覆盖点2,3对应边为2->3,3->4,我们就建一条从2->4的边,对于给定[ai,bi]建一条ai->bi+1的边。还有一个问题就是关于区间重复的覆盖,例如区间[2,5]和区间[3,6],可以覆盖区间[2,6],如果只按照上面建图是无法连通[2,6]的,所以我们需要给每一个点加一个反向边,就是从点i+1 ->点i且权值为0,这样当通过2->5走到5时我们无法走其他点就可以往回走,走到3,再走3->6这条边。

  解法二:线段树,做完以后发现就我用了最短路,很多大佬用的都是线段树,我太菜了数据结构没学好,没想到,挖坑待补。。。。

代码实现:

dijkstra解法:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#define lowbit(x) (x&(-x))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = ;
const int INF = 0x7FFFFFFF;
const LL INFF =0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-;
const LL mod = 1e9 + ;
const int maxn = 1e6 + ;
const int maxm = 4e6 + ; int n, m, first[maxn], sign; struct Edge{
int to, w, next;
}edge[maxn * ]; void init(){
for(int i = ; i <= n; i++){
first[i] = -;
}
sign = ;
} void addEdge(int u,int v,int w){
edge[sign].to = v;
edge[sign].w = w;
edge[sign].next = first[u];
first[u] = sign++;
} struct Node{
int to;
LL cost;
Node(){}
Node(int tt, LL cc):to(tt),cost(cc){}
friend bool operator < (const Node &a, const Node &b){
return a.cost > b.cost;
}
}; LL dist[maxn];
int vis[maxn]; LL dijkstra(int s, int t){
for(int i = ; i <= n; i++){
dist[i] = INFF;
vis[i] = ;
}
priority_queue<Node> que;
que.push(Node(s,));
while(!que.empty())
{
Node now = que.top();
//printf("%d\n",now.to);
que.pop();
if(!vis[now.to]){
vis[now.to] = ;
dist[now.to] = now.cost;
for(int i = first[now.to];~i;i = edge[i].next){
int to = edge[i].to;
LL w = edge[i].w;
if(!vis[to]){
que.push(Node(to,now.cost + w));
}
}
}
}
return dist[t] == INFF ? - : dist[t];
}
int main()
{
int s, t;
scanf("%d%d%d",&m,&s,&t);
n = t + ;
init();
for(int i = ; i<= m; i++){
int u, v, w;
scanf("%d%d%d",&u,&v,&w);
addEdge(u,v + ,w);
}
for(int i = s + ; i <= n; i++){
addEdge(i ,i - , );
}
printf("%lld\n",dijkstra(s, t+));
return ;
}

线段树解法:

/*待补。。。。*/

B CWL的女朋友2

题目大意:

  题意就是给你一个长度为n的字符串,仅仅包含数组1~9,问你能否拆分成几个部分让他们的和相等,例如:178035可以拆分成三个部分1 + 7 = 8 = 0 + 3 + 5。

解题思路:

  数据范围都很小直接暴力模拟就行,分段的数字和一定能被所有数字总和整除,所以分解总和的因子暴力枚举每一个因子看是否能分解出几段数字都和他相等,(tip:总和本身也是自己因子,但是不可行,因为这样他就只有自己本身一段了,不符合题意)

代码实现:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#define lowbit(x) (x&(-x))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = ;
const int INF = 0x7FFFFFFF;
const LL INFF =0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-;
const LL mod = 1e9 + ;
const int maxn = 1e7 + ;
const int maxm = 4e6 + ; int arr[];
char str[];
vector<int> vec; void fj(int x){
for(int i = ; i * i <= x; i++){
if(x % i ==){
vec.push_back(i);
if(x / i != i)
vec.push_back(x/i);
}
}
} int main()
{
int n;
int sum, cnt;
while(~scanf("%d",&n)){
getchar();
sum = ;
scanf("%s",str);
for(int i = ; i < n; i++){
arr[i] = str[i] - '';
sum += arr[i];
}
vec.push_back();
fj(sum);
bool f,fa = false;
for(auto val : vec){
cnt = ;
for(int i = ;i < n ;i ++){
cnt += arr[i];
if(cnt == val){
cnt = ;
}
}
if(cnt == ){
fa = true;
break;
}
}
fa ? puts("YES") : puts("NO");
vec.clear();
}
}

C Hang的闯关

题目大意:

  给你前12层每一层Hang身上有的数字,并且告诉你没到一层就会获得一定的0和1(具体多少需要自己猜规律),然后某个数字达到一定数量就会合成,现在告诉你n让你计算Hang身上的数字是多少。

解题思路:

  规律通过关材可以很快的发现奇数层获得0,偶数层获得1和0,两个0合成一个1,三个1合成一个2,四个2合成一个3,我的做法是把0全部转换成1,再看1能够合成的数字,一个2需要3个1,一个3需要12个1,一个4需要60个1,规律3*4....*9,因为最多可以合成的数字只有9(n <= 1e7),我们只要遍历从9开始看1的数量能组成几个9,几个8,直接输出就行。

代码实现:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#define lowbit(x) (x&(-x))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = ;
const int INF = 0x7FFFFFFF;
const LL INFF =0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-;
const LL mod = 1e9 + ;
const int maxn = 1e7 + ;
const int maxm = 4e6 + ; int arr[];
int vis[];
int main()
{
int cnt = ,t ,n;
arr[] = ;
for(int i = ; i <= ; i++){
arr[cnt] = arr[cnt - ] * i;
cnt ++;
}
scanf("%d",&t);
int num0,num1;
while(t--){
scanf("%d",&n);
num0 = n;
num1 = n/;
num1 += num0/;
num0 %= ;
memset(vis,,sizeof(vis));
// debug(num1);
// debug(num0);
for(int i = ; i>= ;i--){
if(num1 / arr[i]!= ){
vis[i] = num1/arr[i];
num1 %= arr[i];
}
} for(int i = ; i >= ;i--){
while(vis[i]){
printf("%d",i);
vis[i]--;
}
}
if(num0) puts(""); else puts("");
}
return ;
}

D/E 这不傻逼题吗(Easy)/(Hard)

题目大意:

  给你n个选择题,每个题a[i]个选项,在保证每一个题都选对的情况下,如果所有答案往后错填一位,第n位移动到第一位,请你计算做对题目的期望。

解题思路:

  这题我一开始是没想法的(太菜了)队友都秒A的,我D先写了个暴力全排列去计算期望(暴力大法好),然后E题想了挺久,我们考虑先考虑做对第i到题的概率,如果a[i - 1] > a[i] 那个大于a[i]的的部分是不可能是正确答案的,如果a[i - 1] < a[i]那个a[i - 1]部分全部都可能是正确答案,所以a[i]可能做对部分只有min(a[i],a[i-1]),而总的可以能性有a[i] * a[i-1]种,即使p(i) = min(a[i],a[i-1]) / (a[i] * a[i-1]) 做对每一题的权值为1,我们可以直接for一遍把所有题的的期望相加就可以了。(做完后发现min(a[i],a[i-1]) / (a[i] * a[i-1]) 可以化简为 1.0/max(a[i],a[i-1]) )

代码实现:

全排列暴力:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#define lowbit(x) (x&(-x))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = ;
const int INF = 0x7FFFFFFF;
const LL INFF =0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-;
const LL mod = 1e9 + ;
const int maxn = 1e6 + ;
const int maxm = 4e6 + ; int n, sign = ;
int arr[];
int re[][];
string str[maxn];
void dfs(int deep,LL ji){
if(deep > n){
str[sign++] = to_string(ji);
return ;
}
for(int i = ; i <= arr[deep]; i++){
dfs(deep + ,ji * + i);
}
}
int main()
{
scanf("%d",&n);
for(int i = ; i <= n; i++){
scanf("%d",arr+i);
}
dfs(,0LL);
int cnt, ans;
double fz = 0.0;
for(int i = ; i < sign; i++){
ans = ;
for(int j = ; j < n; j++){
cnt = (j + ) % n;
if(str[i][j] == str[i][cnt]) ans ++;
}
fz += ans;
}
printf("%.3f",fz/sign);
}

正解:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#define lowbit(x) (x&(-x))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = ;
const int INF = 0x7FFFFFFF;
const LL INFF =0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-;
const LL mod = 1e9 + ;
const int maxn = 1e6 + ;
const int maxm = 4e6 + ; long long int a[];
int main()
{
int n;
long long A,B,C;
scanf("%d",&n);
scanf("%lld%lld%lld%lld",&A,&B,&C,&a[]);
for (int i=; i <= n; i++){
a[i] = ((long long)a[i-]*A+B)%;
}
for (int i = ; i <= n; i++){
a[i] = a[i]%C+;
}
double ans = 0.0;
for (int i = ; i <= n; i++){
ans += double(min(a[i],a[i-]))/double(a[i]*a[i-]);
}
ans += double(min(a[n],a[]))/double(a[n]*a[]);
printf("%.3f\n",ans);
return ;
}

题目大意:

  

解题思路:

  瞎猜。。。。

  具体证明:https://www.plsseer0qaq.top/index.php/acm/196/?tdsourcetag=s_pctim_aiomsg

代码实现:

print(1)

FJUT2019暑假第二次周赛题解的更多相关文章

  1. FJUT2019暑假周赛三部分题解

    A本来想改到q<1e5,让你们预处理的,然后想了哈作为个逆元模板题吧= =,做不出来自行反思. B贴个题面 因为只有一次机会,那么也就是两点分布期望E = p了,先说说大家的做法,先求出每个n的 ...

  2. FJUT2019暑假周赛一题解

    A.排队问题*-* 题意就是有长度为L的序列,每位的取值可以是'f'或者'm',问不包含'fff'和'fmf'的个数. 打表找规律 不难找出递推公式为F[n] = F[n-1] + F[n-3] + ...

  3. 第二场周赛(递归递推个人Rank赛)——题解

    很高兴给大家出题,本次难度低于上一场,新生的六个题都可以直接裸递归式或者裸递推式解决,对于老生的汉诺塔3,需要找出一般式,后两题分别为裸ST算法(或线段树)/线性DP. 正确的难度顺序为 种花 角谷定 ...

  4. 暑假训练round 3 题解

    今天做题运气出奇的好,除了几处小错误调试之后忘记改掉了……最后还AK了……虽然题目不难,学长也说是福利局,但是对个人的鼓励作用还是挺大的……至此暑假训练就结束了,也算没有遗憾……. 题解如下: Pro ...

  5. ACM团队周赛题解(1)

    这次周赛题目拉了CF315和CF349两套题. 因为我代码模板较长,便只放出关键代码部分 #define ll long long #define MMT(s,a) memset(s, a, size ...

  6. K-集合 (JXNU第二次周赛1006)set/平衡树

    K-集合 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submissi ...

  7. 【CQ18阶梯赛第二场】题解

    [A-H国的身份证号码I] 用N个for语句可以搞定,但是写起来不方便,所以搜索. dfs(w,num,p)表示搜索完前w位,前面x组成的数位num,最后以为为p. 如果搜索到第N位,则表示num满足 ...

  8. 《剑指offer 第二版》题解

    剑指Offer 按题号排序 面试题 3:数组中重复的数字 面试题 4:二维数组中的查找 面试题 5:替换空格 面试题 6:从头到尾打印链表 面试题 7:重建二叉树 面试题 8:二叉树的下一个节点 面试 ...

  9. 9.18考试 第二题Dinner题解

    当时初步感觉是一个类似动归或者贪心的神题,然而由于本题已经给出顺序,贪心貌似并没有什么道理,所以放弃贪心.然后又由于这是一个环的问题,我想到了“合并石子”那种环转链的思路,然后就是一个O(n^2*m) ...

随机推荐

  1. Bash语句中的循环语句注意事项

    case #!/bin/bash case $1 in 9) echo "nine" ;; 8) echo "eight" ;; 7) echo "s ...

  2. hdu1045 炮台的配置 dfs

    只要炮台在同一行或者同一列,就可以互相摧毁,遇到墙则无法对墙后的炮台造成伤害,可以通过dfs搜索n*n的方格,全部搜完算一轮,计算炮台数,并保存其最大值. 其中对于t编号的炮台,位置可以计算出是(t/ ...

  3. .gitignore排除(不忽略)二级以上目录下的文件或目录

    在.gitignore中,结合使用/*和!filename的语法,可以达到除特定文件或目录外全部忽略的目的.但当希望不忽略的文件或目录在二级或多级目录下时,如果这样写 /* !/sub/subsub/ ...

  4. 基础的Linux命令(二)

    本文介绍两大类命令,都是最基础的部分 系统状态监测命令 工作目录切换命令 一.系统状态监测命令 1. ifconfig 命令 用于获取网卡配置与网络状态等信息 如下图:inet后面是 IP 地址,et ...

  5. 从字节码来分析,i++与++i区别

    ++/-- 是一种特殊的算术运算符,在算术运算符中需要两个操作数来进行运算,而自增自减运算符是一个操作数 前缀自增(++a):先进行自增运算,再进行表达式运算: 后缀自增(a++):先进行表达式运算, ...

  6. [Unity] Unity 2019.1.14f 在Terrain中使用Paint Texture的方法

    1.点击Terrain中的Paint Texture按钮2.将按钮下面的下拉菜单选择paint texture3.点击Edit Terrain Layers按钮T4.点击弹出菜单的Create Lay ...

  7. [模板] dijkstra (堆优化)

    复杂度O(mlogn) 输入起点s,可以得到从起点到各点的最短路距离数组dis[i] 过程: 1.初始化:清空标记数组,初始化距离数组设为inf,起点距离设为0,开优先队列,搜索起点 2.搜索:取出队 ...

  8. SQL 分组内求最大N个或最小N个

    题目描述 表 Employee +----+-------+--------+--------------+ | Id | Name | Salary | DepartmentId | +----+- ...

  9. java接口自动化(二) - 接口测试的用例设计

    1.简介 在这篇文章里,我们来学习一下接口测试用例设计,主要是来学习一些用例设计要点.其实说白了,接口用例设计和功能用例设计差不多,照猫画虎即可.不要把它想象的多么高大上,多么的难,其实一样,以前怎么 ...

  10. 03 串口发送端口Rs232之简单驱动1

    前言: 最近想实际做两个项目,认真学习怎么做一个系统,所以在看FPGA小梅哥2019的培训课程,发现他是从各个模块讲起,就是没有直接讲一个整体的系统,而是从一些模块开始,如串口发送.刚开始我想直接创造 ...