2017杭电ACM集训队单人排位赛 - 2 题解
1001,水题,直接模拟即可。比赛中开局连wa三发,因为把int写成了bool..
1002,积分题,比赛中找到了下面这个积分公式,

但是并没什么用,,因为带入以后存在误差,估计是展开了以后出现了误差。然后用自适应simpson即可。大白书上的模板不怎么好用(虽然能过),优化版的模板如下(本题AC代码):
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<algorithm>
#include<cmath>
#include<vector>
#include<list>
#include<fstream>
#include<sstream>
#include<cassert>
#include<bitset>
#define showtime printf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
#define MP make_pair
#define PII pair<int,int>
#define PFI pair<double,int>
#define PLL pair<ll,ll>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
typedef vector<long long> vec;
typedef vector<vec> mat;
inline int popcnt(int x){return __builtin_popcount(x); }
inline int clz(int x){return __builtin_clz(x);} //末尾的 0,即对 lowbit 取log
inline int clz(LL x){return __builtin_clzll(x);}
inline int lg2(int x){ return !x ? - : -clz(x);}
inline int lg2(LL x){ return !x ? - : -clz(x);}
inline int __lcm(int x, int y){ return x / __gcd(x, y) * y; }
const double eps = 1e-;
const double PI = acos(-.);
const double E = 2.71828182845904523536;
const int MOD = (int)1e9+;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const ull BAS = ;
const int M = 1e5 + ;
const int N = 1e5 + ; double v1, v2, x, k; double f(double t){
// 表达式
return k / (((x-v2*t)*(x-v2*t)) + (t*v1) * (t*v1));
}
double simpson(double l,double r){ // simpson公式
return 1.0 / 6.0 * (r - l) * (f(l) + * f((l+r)/2.0) + f(r));
}
double integral(double l,double r){
double mid = (l + r) / 2.0;
double ret = simpson(l,r); // 二分逼近
if(fabs(ret - simpson(l,mid)-simpson(mid,r)) < eps)
return ret;
else
return integral(l,mid) + integral(mid,r);
}
/*
k
---------------------
(x-v2*t)^2 + (t*v1)^2
*/
int main(){
int T;
cin >> T;
while(T --){
cin >> v1 >> v2 >> x >> k;
printf("%.2f\n", integral(, 1e18));
}
return ;
}
1002
1003,用dfs不能过,因为有环,那么谁先更新谁后更新对答案有偏差,因此采用优先队列的dij来做。代码如下:
#include <bits/stdc++.h>
#define t_mid (l+r>>1)
#define ls (o<<1)
#define rs (o<<1|1)
#define lson ls,l,t_mid
#define rson rs,t_mid+1,r
using namespace std;
const int N = 1e5 + ;
typedef long long ll;
typedef pair<int,int> pii;
const int mod = 1e9 + ; int T;
int n, m;
int a[N];
vector<pii> G[N]; int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
priority_queue<pii,vector<pii>,greater<pii> > Q;
for(int i=;i<=n;i++) {scanf("%d",a+i); Q.push(pii(a[i], i)); G[i].clear();}
for(int i=;i<=m;i++)
{
int x, y, z;
scanf("%d%d%d",&x,&y,&z);
G[x].push_back(pii(y,z));
G[y].push_back(pii(x,z));
}
while(!Q.empty())
{
pii p = Q.top(); Q.pop();
int u1 = p.second;
for(pii pp : G[u1])
{
int u2 = pp.first;
int v = pp.second;
if(a[v] > a[u1] + a[u2])
{
a[v] = a[u1] + a[u2];
Q.push(pii(a[v], v));
}
}
}
for(int i=;i<=n;i++) printf("%d%c",a[i],i==n?'\n':' ');
}
return ;
}
1003
1004,水题。
1005,3!枚举一下3种字符的排列顺序,得到此时的目标串,然后和原串匹配一下得到在目标串中的连续的最长的子串,这个长度就是不需要动的牌,然后所有情况比较得到最优解即可。需要是连续的是因为每次只能把牌放到最前和最后,不难证明可以成立。同时这个匹配的方法可以dp,也可以暴力。这个dp的转移还是需要注意一下的。代码如下:
#include <bits/stdc++.h>
#define t_mid (l+r>>1)
#define ls (o<<1)
#define rs (o<<1|1)
#define lson ls,l,t_mid
#define rson rs,t_mid+1,r
using namespace std;
const int N = 1e5 + ;
typedef long long ll;
typedef pair<int,int> pii;
const int mod = 1e9 + ; int T;
char s[];
char t[];
int cnt[];
char need[][];
char str[];
int ans; int dp[][];
void solve()
{
// s -> str
//printf("%s -- %s\n",s+1,str+1);
for(int l=;l<=;l++)
{
for(int r=l+;r<=;r++)
{
int temp = ;
for(int i=;i<=;i++)
{
if(s[i] == str[l+temp])
{
temp++;
}
}
if(temp == r - l + ) ans = max(ans, r - l + );
}
}
/*memset(dp,0,sizeof dp);
for(int i=1;i<=13;i++)
{
for(int j=1;j<=13;j++)
{
if(s[i] == str[j])
{
dp[i][j] = dp[i-1][j-1] + 1;
}
else dp[i][j] = dp[i-1][j];
ans = max(ans, dp[i][j]);
}
}*/
} int main()
{
// 3 1 2
//printf("%d %d %d ?\n",'a','1','A');
scanf("%d",&T);
while(T--)
{
scanf("%s",s+);
memcpy(t,s,sizeof t);
sort(t+,t++);
memset(cnt,,sizeof cnt);
memset(need,,sizeof need);
int now = ;
int p = ;
for(;;now++)
{
if(!isdigit(t[now])) break;
need[][++p] = t[now];
}
cnt[] = now - ;
p = ;
for(;;now++)
{
if(t[now] < 'A' || t[now] > 'Z') break;
need[][++p] = t[now];
}
cnt[] = p;
p = ;
for(;now<=;now++)
{
need[][++p] = t[now];
}
cnt[] = p; ans = ;
memset(str,,sizeof str);
strcat(str+,need[]+); strcat(str+,need[]+); strcat(str+,need[]+);
solve();
memset(str,,sizeof str);
strcat(str+,need[]+); strcat(str+,need[]+); strcat(str+,need[]+);
solve();
memset(str,,sizeof str);
strcat(str+,need[]+); strcat(str+,need[]+); strcat(str+,need[]+);
solve();
memset(str,,sizeof str);
strcat(str+,need[]+); strcat(str+,need[]+); strcat(str+,need[]+);
solve();
memset(str,,sizeof str);
strcat(str+,need[]+); strcat(str+,need[]+); strcat(str+,need[]+);
solve();
memset(str,,sizeof str);
strcat(str+,need[]+); strcat(str+,need[]+); strcat(str+,need[]+);
solve();
printf("%d\n",-ans);
}
return ;
}
1005
1006,做这题前可以先做一下hdu2045。在该题中两个颜色相同的位置(称之为分隔处)把这个串分成了两部分,这两个相同颜色的位置假设颜色已经固定了(最后只要把答案再乘以k即可),那么剩余的有(k-1)种颜色可选择,设f[i]为长度为i的合理串的种数,那么这个状态可以从以下两个状态转移过来:
1.长度为i-1的合理的串,那么其最后一个颜色一定与分隔处不同,那么第i个位置只剩下了(k-2)种选择,贡献为(k-2)*f[i-1]。
2.长度为i-1的不合理的串,那么前i-2个必须合理,否则不能转移到i处,同时不可能是i-2和i-1处的颜色不同(如果不同也无法转移到i处),只能是i-1处和分隔处的颜色相同才行,那么i这个地方有(k-1)种选择,贡献为(k-1)*f[i-2]。
综上可得,f[i] = f[i-1]*(k-2) + f[i-2]*(k-1)(可以发现这种推算f的方式和hdu2045中类似)。边界处手算一下即可。得到了以后就可以做了。假设分隔位置为l和r,那么新的两部分的长度为别为Len1=|r-l|-1,Len2=n-|r-l|-1。那么最后的答案为k*f[Len1]*f[Len2] % mod。
同时,还有别的方法推f数组,每次扩张一个新长度时,只有k-1种选择(因为不能和分隔处颜色相同),所以总次数为(k-1)^i,这其中有重复的,计算方法如下:如果i-1处和分隔处颜色相同,那么i这个位置一定不会和相邻位置颜色相同;当i-1处和分隔处颜色不同,这时才有可能i的颜色和i-1处的重合,这种情况的总数是,前i-1个位置的正确总数,即f[i-1],那么f[i] = (k-1)^i - f[i-1]。后面的计算方法类似。
代码如下(第一种推算f数组的方法):
#include <bits/stdc++.h>
#define t_mid (l+r>>1)
#define ls (o<<1)
#define rs (o<<1|1)
#define lson ls,l,t_mid
#define rson rs,t_mid+1,r
using namespace std;
const int N = 1e5 + ;
typedef long long ll;
typedef pair<int,int> pii;
const int mod = 1e9 + ; int n,m,k;
int f[N]; int main()
{
while(scanf("%d%d%d",&n,&m,&k) == )
{
f[] = k-;
f[] = (ll)(k-) * (k-) % mod;
for(int i=;i<=n;i++)
{
f[i] = ((ll)(k-)*f[i-] + (ll)(k-)*f[i-]) % mod;
}
while(m--)
{
int l, r;
scanf("%d%d",&l,&r);
int ans = (ll)k*f[abs(r-l)-] % mod * (f[n-abs(r-l)-]) % mod;
printf("%d\n",ans);
}
}
return ;
}
1006
1007,分奇数和偶数作为起点进行扫描,维护遇到的最小的前缀和并更新答案即可。
1008,结论题。如果两点是相邻的则能追到,否则不行。理由是如果距离大于等于2,走的人走哪里,打断下一条路即可。
1009,分情况讨论即可。注意即使一开始全部相同,也必须要交换(也就是说要满足,只能换相同的两个字母)。
1010,因为位数少,直接暴力即可。如果位数多,可以考虑数位dp。
GY.png)
2017杭电ACM集训队单人排位赛 - 2 题解的更多相关文章
- 2017杭电ACM集训队单人排位赛 - 6
2017杭电ACM集训队单人排位赛 - 6 排名 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 59 1 X X 1 1 X X 0 1 ...
- 高手看了,感觉惨不忍睹——关于“【ACM】杭电ACM题一直WA求高手看看代码”
按 被中科大软件学院二年级研究生 HCOONa 骂为“误人子弟”之后(见:<中科大的那位,敢更不要脸点么?> ),继续“误人子弟”. 问题: 题目:(感谢 王爱学志 网友对题目给出的翻译) ...
- 杭电ACM题单
杭电acm题目分类版本1 1002 简单的大数 1003 DP经典问题,最大连续子段和 1004 简单题 1005 找规律(循环点) 1006 感觉有点BT的题,我到现在还没过 1007 经典问题,最 ...
- 杭电acm习题分类
专注于C语言编程 C Programming Practice Problems (Programming Challenges) 杭电ACM题目分类 基础题:1000.1001.1004.1005. ...
- 杭电ACM分类
杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...
- 杭电ACM(1002) -- A + B Problem II 大数相加 -提交通过
杭电ACM(1002)大数相加 A + B Problem II Problem DescriptionI have a very simple problem for you. Given two ...
- 杭电acm阶段之理工大版
想參加全国软件设计大赛C/C++语言组的同学,假设前一篇<C和指针课后练习题总结>没看完的,请先看完而且依照上面的训练做完,然后做以下的训练. 传送门:http://blog.csdn.n ...
- 杭电acm 1076题
水题,一个求闰年的题目,复习一下闰年的求法.... 1,如果能被4整除但不能被100整除的是闰年 2,能被400整除的是闰年 题目大意是:给定一个开始年份T以及一个正数N,要求求出从T开始,到了哪一年 ...
- 杭电acm 1037题
本题应该是迄今为止最为简单的一道题,只有一组输入,输出也简单.... /****************************************** 杭电acm 1037题 已AC ***** ...
随机推荐
- SVN_04建库
示范加入一个代码库[Repository] [1]点击Repository右键,创建一个新库 (常规FSFS存储库) [2]在下面所看到的文本框中输入库名称 只创建空的库 创建完库后,没有任何内容在里 ...
- C# UTF-8文件带BOM和不带BOM文件的转换
读取INI文件使用的是GetPrivateProfileString方法,自己读写ini文件没有问题. 调用C++的API对同一个ini文件进行处理后,发现首个Section的值读不出来:发现是API ...
- 4_PHP流程控制语句_2_循环结构
以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. PHP流程控制共有3种类型:条件控制结构.循环结构以及程序跳转和终止语句. 4.2 循环结构 4.2.1 whil ...
- java线程的五种状态
五种状态 开始状态(new) 就绪状态(runnable) 运行状态(running) 阻塞状态(blocked) 结束状态(dead) 状态变化 1.线程刚创建时,是new状态 2.线程调用了sta ...
- CocoaPods - 发布自己的模块(公有库、私有库)
CocoaPods发布框架到远程公有库 1.编写代码~上传远程仓库 git init git add . git commit -m '提交到本地分支' //关联远程仓库 git remote add ...
- 【转载】如何自己DIY组装一台台式电脑
针对很多懂计算机的人员来说,有时候都希望自己DIY组装一台台式机,来达到自己的个性化要求以及省钱.其实自己DIY组装一台电脑也很简单,将相应的CPU处理器.主板.内存条.硬盘.固态硬盘.电脑机箱.屏幕 ...
- source tree每次push都需要密码的解决方法
Windows首先可以考虑使用GitHub for Windows,它已经包含了该助手,或者可以下载对应系统的版本:Windows 7.Windows 8.Source 版本,然后解压缩文件并将里面的 ...
- 分享一个仿网易新闻客户端iPhone版的标签式导航ViewController
该Controller是一个容器,用于容纳其他的controller.效果与网易新闻客户端的标签式导航基本一样: (1)点击上面的标签,可以切换到对应的controller,标签下面的红色提示条的长度 ...
- 微信APP支付(基于Java实现微信APP支付)
步骤: 导入maven依赖 <!--微信支付--> <dependency> <groupId>com.github.wxpay</groupId> & ...
- 1.利用BeanMap进行对象与Map的相互转换
javabean与map的转换有很多种方式,比如: 1.通过ObjectMapper先将bean转换为json,再将json转换为map,但是这种方法比较绕,且效率很低,经测试,循环转换10000个b ...