2014ACM/ICPC亚洲区鞍山站 清华命题
A http://acm.hdu.edu.cn/showproblem.php?pid=5070
先跳过。
B http://acm.hdu.edu.cn/showproblem.php?pid=5071
维护一个聊天队列,有8种操作,每次操作完要打印对应的信息,认真读题,按题意模拟,一维数组模拟队列就可以,5000操作,交换删除等on暴力复杂度也不会超时。
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
const int M=;
char a[M];
char b[M][M]={"","Add","Close","Chat","Rotate","Prior","Choose","Top","Untop"};
map<int,int> mp;
int sta[],top,cnt,x;
void success(){
puts("success.");
}
void invalid(){
puts("invalid priority.");
}
void Empty(){
puts("empty.");
}
void solve1(){
for(int i=;i<cnt;i++){
if(sta[i]==x){
puts("same priority.");
return ;
}
}
sta[cnt++]=x;
success();
}
void solve2(){
for(int i=;i<cnt;i++){
if(sta[i]==x){
if(top==x) top=-;
for(int j=i;j<cnt-;j++){
sta[j]=sta[j+];
}
cnt--;
printf("close %d with %d.\n",x,mp[x]);
mp.erase(x);
return ;
}
}
invalid();
}
void solve3(){
if(!cnt){
Empty();
return ;
}
if(top!=-){
mp[top]+=x;
success();
return ;
}
mp[sta[]]+=x;
success();
}
void solve4(int id){
if(id<||id>cnt){
puts("out of range.");
return ;
}
int tmp=sta[id-];
for(int i=id-;i>;i--){
sta[i]=sta[i-];
}
sta[]=tmp;
success();
}
void solve5(){
if(!cnt){
Empty();
return ;
}
int id=;
for(int i=;i<cnt;i++){
if(sta[i]>sta[id]){
id=i;
}
}
solve4(id+);
}
void solve6(){
for(int i=;i<cnt;i++){
if(sta[i]==x){
solve4(i+);
return ;
}
}
invalid();
}
void solve7(){
for(int i=;i<cnt;i++){
if(sta[i]==x){
top=x;
success();
return ;
}
}
invalid();
}
void solve8(){
if(top!=-){
top=-;
success();
return ;
}
puts("no such person.");
}
int main(){
int t,n;
while(~scanf("%d",&t)){
while(t--){
scanf("%d",&n);
int cas=;
top=-,cnt=;
mp.clear();
while(n--){
scanf("%s",a);
int id=;
for(int i=;i<=;i++){
if(!strcmp(a,b[i])){
id=i;
break;
}
}
if(id!=&&id!=){
scanf("%d",&x);
}
printf("Operation #%d: ",cas++);
if(id==){
solve1();
}
else if(id==){
solve2();
}
else if(id==){
solve3();
}
else if(id==){
solve4(x);
}
else if(id==){
solve5();
}
else if(id==){
solve6();
}
else if(id==){
solve7();
}
else{
solve8();
}
}
if(top!=-&&mp[top]){
printf("Bye %d: %d\n",top,mp[top]);
}
for(int i=;i<cnt;i++){
if(top!=sta[i]&&mp[sta[i]]){
printf("Bye %d: %d\n",sta[i],mp[sta[i]]);
}
}
}
}
return ;
}
C http://acm.hdu.edu.cn/showproblem.php?pid=5072
输入n个数,n<=10^5,其中选出3个数,满足两两之间互质,或者两两之间都不互质,问有多少种不同的选法。
解法:暴力n^3,然后加3次gcd判断,统计。明显超时,但可以用来测测。
根据 模型请参考 《算法竞赛入门经典 训练指南》 p105 问题6,大白书。
那个模型是这样的,给定空间n个点n==1000,没有3点共线,每两个点之间都用红色或黑色边连接,求3条边同色的三角形个数。
那么对于这个题,我们可以把每个数当做三角形的点,数与数之间互质当做红边,不互质当做黑边,那么就是这个问题了。
三角形这个题,可以求反面,求出非单色三角形,就可以用总数扣去得到答案。对于非单色三角形,必然有两个点连的两条边不同色。
所以对每个点,如果有ai条红色边,就有n-1-ai条蓝色边,ai*(n-1-ai)就是该点形成的非单色三角形,因为一个三角形会算两次,(必然有两个点连的两条边不同色)。所以除二。
对于上面这个题,一样的方法,对每个数,求出有多少个互质的,假设求出来是bi,那么不互质的就是(n-1-bi),那么这个数能贡献的答案就是bi*(n-1-bi),因为每种情况会重复算一次,所以最后答案除2就是不合法的情况,用总数减去就是题目所求。
问题只剩下如何求bi,多少个互质的,然后就是二进制暴力质因子,容斥原理++--,理解一下。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const int M=1e5+;
int pri[M],mark[M],pricnt;//mark[i]存i的最小因子,素数时mark[i]==i
void sieve_primes() { //筛素数
pricnt=;
mt(mark,);
mark[]=mark[]=;
for(int i=; i<M; i++) {
if(!mark[i]) pri[pricnt++]=mark[i]=i;
for(int j=; pri[j]*i<M; j++) {
mark[i*pri[j]]=pri[j];
if(!(i%pri[j])) break;
}
}
}
int fac[];
int find_fac_before_sieve(int n) { //筛完素数后用,n<M
int cnt=;
while(mark[n]!=) {
fac[cnt++]=mark[n];
n/=mark[n];
}
return cnt;
}
int num[M];
int lf;
void dfs(int now,int sum){
if(now==lf){
num[sum]++;
return ;
}
dfs(now+,sum);
dfs(now+,sum*fac[now]);
}
LL help;
void dfs_ans(int now,int sum,int cnt){
if(now==lf){
// if(!cnt) return ;
if(cnt&) help-=num[sum];
else help+=num[sum];
return ;
}
dfs_ans(now+,sum,cnt);
dfs_ans(now+,sum*fac[now],cnt+);
}
int a[M];
int main(){
sieve_primes();
int t,n;
while(~scanf("%d",&t)){
while(t--){
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d",&a[i]);
}
mt(num,);
for(int i=;i<n;i++){
lf=find_fac_before_sieve(a[i]);
lf=unique(fac,fac+lf)-fac;
dfs(,);
}
LL ans=;
for(int i=;i<n;i++){
lf=find_fac_before_sieve(a[i]);
lf=unique(fac,fac+lf)-fac;
help=;
dfs_ans(,,);
if(a[i]==) help--;
ans+=help*(n--help);
}
printf("%lld\n",1LL*n*(n-)*(n-)/-ans/);
}
}
return ;
}
D http://acm.hdu.edu.cn/showproblem.php?pid=5073
输入一维数轴上n个坐标,每个点重量是1,可以允许最多移动k个点,允许移动到同一个位置,问如何移动使得(每个点到重心的距离的平方)的和最小。
因为重量都是1,所以重心就会落在n个坐标的平均值位置。
一个先决条件是,k个点一定都要移动,那么剩下n-k个点去求那个权值。
因为移动的k个点可以都移动到剩下点的重心去,那么他们对权值的贡献就是零,相当于直接删去。
还有一个条件是,为了使得大家距离重心更近,那么肯定留下的n-k个点要连续,这样肯定比离散的距离重心近。
所以我们将坐标排序,枚举起点,求长度为n-k这一段的权值,最后取最小值。
问题就需要尽快的求出一个连续段的权值。
对于距离平方求和,就是(Xi-Xavg)^2=Xi^2-2*Xi*Xavg+Xavg^2 (L<=i<=R)
求均值预处理前n项和即可,第一项就预处理前n项平方和。
#include<cstdio>
#include<algorithm>
using namespace std;
const int M=5e4+;
int a[M];
int main(){
int t,n,m;
while(~scanf("%d",&t)){
while(t--){
scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
scanf("%d",&a[i]);
}
if(n==m){
puts("");
continue;
}
sort(a,a+n);
double sum=,sum2=;
int cnt=n-m;
for(int i=;i<cnt;i++){
sum+=a[i];
sum2+=1.0*a[i]*a[i];
}
double ans=sum2-*(sum/cnt)*sum+sum/cnt*sum;
for(int i=cnt;i<n;i++){
sum+=a[i];
sum-=a[i-cnt];
sum2+=1.0*a[i]*a[i];
sum2-=1.0*a[i-cnt]*a[i-cnt];
double now=sum2-*(sum/cnt)*sum+sum/cnt*sum;
ans=min(ans,now);
}
printf("%.10f\n",ans);
}
}
return ;
}
E http://acm.hdu.edu.cn/showproblem.php?pid=5074
输入n个数的序列,序列的得分是ai和ai+1之间贡献的,也就是有n-1个得分。数字一定是1到m的,输入会给出m*m的矩阵,即矩阵mat【i】【j】 表示 i 在 j 前面的得分。序列中值为1到m的是必须选择该值,值为-1的是你可以在1到m中任意选一个放在该位置,最后要求序列可能得到的最大分数。
解法:若枚举,如果n个都是-1,每一个有1到m种情况,总情况数就是m的n次方,50^100,观察发现,有最优子结构性质,即dp【n】【m】表示前n个以m为结尾所能得到的最大分数。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
const int M=;
int dp[M<<][M],a[M][M],b[M<<];
int main(){
int t,n,m;
while(~scanf("%d",&t)){
while(t--){
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
for(int j=;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
for(int i=;i<=n;i++){
scanf("%d",&b[i]);
}
mt(dp,-);
if(b[]==-){
for(int j=;j<=m;j++){
dp[][j]=;
}
}
else{
dp[][b[]]=;
}
for(int i=;i<n;i++){
for(int j=;j<=m;j++){
if(dp[i][j]==-) continue;
if(b[i+]>){
dp[i+][b[i+]]=max(dp[i+][b[i+]],dp[i][j]+a[j][b[i+]]);
continue;
}
for(int k=;k<=m;k++){
dp[i+][k]=max(dp[i+][k],dp[i][j]+a[j][k]);
}
}
}
int ans=;
for(int j=;j<=m;j++){
ans=max(ans,dp[n][j]);
}
printf("%d\n",ans);
}
}
return ;
}
I http://acm.hdu.edu.cn/showproblem.php?pid=5078
输入n个点,每个点有时间t,坐标x,y。定义相邻两点之间的难度为距离/时间差,求最大的难度。
解法:按照定义算相邻两个的难度,取最大值。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int M=1e3+;
struct G{
double t,x,y;
}g[M];
double f(G a,G b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))/(b.t-a.t);
}
int main(){
int t,n;
while(~scanf("%d",&t)){
while(t--){
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%lf%lf%lf",&g[i].t,&g[i].x,&g[i].y);
}
double ans=f(g[],g[]);
for(int i=;i<n;i++){
ans=max(ans,f(g[i-],g[i]));
}
printf("%.10f\n",ans);
}
}
return ;
}
2014ACM/ICPC亚洲区鞍山站 清华命题的更多相关文章
- 2014ACM/ICPC亚洲区西安站 复旦命题
http://codeforces.com/gym/100548 A 签到 问一个序列是不是yes,yes的序列满足每个数都是3的倍数. #include<cstdio> int main ...
- 2014ACM/ICPC亚洲区牡丹江站 浙大命题
A Average Score http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5373 a班有n个人,b班有m个人,bob在a ...
- 2014ACM/ICPC亚洲区鞍山赛区现场赛1009Osu!
鞍山的签到题,求两点之间的距离除以时间的最大值.直接暴力过的. A - Osu! Time Limit:1000MS Memory Limit:262144KB 64bit IO Fo ...
- 2014ACM/ICPC亚洲区西安站 F题 color (组合数学,容斥原理)
题目链接:传送门 题意: n个格子排成一行.我们有m种颜色.能够给这些格子涂色,保证相邻的格子的颜色不同 问,最后恰好使用了k种颜色的方案数. 分析: 看完题目描写叙述之后立刻想到了一个公式 :C(m ...
- 2014ACM/ICPC亚洲区西安站现场赛 F color(二项式反演)
题意:小球排成一排,从m种颜色中选取k种颜色给n个球上色,要求相邻的球的颜色不同,求可行的方案数,答案模1e9+7.T组数据,1<= n, m <= 1e9, 1 <= k < ...
- (HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice's Classified Message(后缀数组)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5558 Problem Description Alice wants to send a classi ...
- 2013ACM/ICPC亚洲区南京站现场赛---Poor Warehouse Keeper(贪心)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4803 Problem Description Jenny is a warehouse keeper. ...
- HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)
Recursive sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- HDU 5952 Counting Cliques 【DFS+剪枝】 (2016ACM/ICPC亚洲区沈阳站)
Counting Cliques Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
随机推荐
- 【转】CSS white-space 属性
定义和用法 white-space 属性设置如何处理元素内的空白. 这个属性声明建立布局过程中如何处理元素中的空白符.值 pre-wrap 和 pre-line 是 CSS 2.1 中新增的. 默认值 ...
- php验证手机号码
大家都应该有这个常识,中国的手机号码都是以数字“1”开头,然后利用“0~9”10个数字组成的11位数字组合,那么我们的验证规则肯定要根据这个思路来写. 根据上面的简单思路,我们便可以写下以下的验证代码 ...
- 从PC跳转至wap
<script language="JavaScript">function mobile_device_detect(url){var thisOS=navigato ...
- xml文件对应的DTD学习
DTD文件: 1.DTD文档主要由(元素,属性,实体,PCDATA,CDATA) 2.声明一个元素:<!ELEMENT 元素名称 (元素内容)> eg: <!ELEMENT pers ...
- Ksoap2 获取webservice返回值的getResponse() 出现的问题
今天写了一个判断记录重复的webservcie 返回布尔类型 // 判断序列号在数据库是否重复 public static boolean isSerialNumExist(String serial ...
- ARM中MMU地址转换理解
首先,我们要分清ARM CPU上的三个地址:虚拟地址(VA,Virtual Address).变换后的虚拟地址(MVA,Modified Virtual Address).物理地址(PA,Physic ...
- JSON对象和String之间的互转及处理
如题,本文列举了一些在web前端开发中常用的转换及处理方式.使用JSON而不是字符串,主要是为了方便处理. JSON:JavaScript 对象表示法(JavaScript Object Notati ...
- Java之有病的policy配置
使用-Djava.security.policy=xxx.policy启动安全策略, 你会想到codesource的配置如此蛋疼么? grant CodeBase "file:////D:/ ...
- MongoDB学习笔记-数据库命令
概念 数据库命令(database command)是一种非常特殊类型的查询.文档的创建.更新.删除及查询都属于数据库命令的范畴,它还包含管理性的任务(比如关闭服务器和克隆数据库).统计数据及执行聚合 ...
- (转)eclipse安装ADT插件重启后不显示Android SDK Manager和Android Virtual Device Manager图标的一种解决办法
文章来源:http://blog.csdn.net/zcyhappy1314/article/details/8307534 下面说的这种情况是在正确安装ADT插件的前提下,重启eclipse后,工具 ...