codeforces 597 div 2
A
题意:
有无限个方块,上面分别是0,1,2.....。若方块i可以被表示为ax+by(x,y>0),则方块为白色,否则为黑色,给出a,b。问黑方块是否有无限个。
分析:
1:若(a,b)=1,由斐蜀等式,则存在an+bm=1(n,m为整数(不保证大于0))。我们只要考虑一个ab区间,若区间内都是白的,那么一定后面都是白色。
我们考虑2|abnm|到2|abnm|+ab-1,这个区间内显然,2|abnm|为ax+by的形式,之后每加一都是加an+bm,而由于从2|abnm|(|nmb|a+|nma|b)开始,累加后an+bm每个数的x‘,y’恒为正。
所以若(a,b)=1,则黑方块一定有限。
2:若(a,b)=k>1,则非k的倍数一定是黑方块,黑方块无穷。
综上,只要求(a,b)就行了。若为1输出Finite,否则为Infinite。
#include<stdio.h>
#include<iostream>
using namespace std;
int gcd(int x,int y)
{
int r=x%y;
while (r!=)
{
x=y;
y=r;
r=x%y;
}
return y;
}
int main()
{
int t,k,a,b;
scanf("%d",&t);
for (k=;k<=t;k++)
{
scanf("%d%d",&a,&b);
if (gcd(a,b)==) printf("Finite\n");
else printf("Infinite\n");
}
return ;
}
of A
B:
题意:
告诉你你能出a个石头,b个布,c个剪刀。(n=a+b+c)
告诉对面这n回合的出法,你要赢round(n/2)回合(平局和输随便啦,只看赢得场数)
问能否做到,不能输出”NO“,能输出YES,并在下一行输出一种可行的方法(R,P,S一行输出)
分析:
就如果它出剪刀,你就看你有没有石头出,有就出呗。。。因为对着前后的不同剪刀出石头是等效的,贪心就行了。
代码:
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
double n;
int i,k,t,a,b,c,s;
char ch;
int ans[];
scanf("%d",&t);
for (k=;k<=t;k++)
{
scanf("%d",&a);
scanf("%d%d%d",&a,&b,&c);
getchar();
n=a+b+c;
s=;
memset(ans,,sizeof(ans));
for (i=;i<=n;i++)
{
ch=getchar();
if (ch=='R'&&b>)
{
b--;
s++;
ans[i]=;
}
if (ch=='P'&&c>)
{
c--;
s++;
ans[i]=;
}
if (ch=='S'&&a>)
{
a--;
s++;
ans[i]=;
}
}
if (s<round(n/)) printf("NO\n");
else
{
printf("YES\n");
for (i=;i<=n;i++)
{
if (ans[i]==) printf("R");
else if (ans[i]==) printf("P");
else if (ans[i]==) printf("S");
else
{
if (a>)
{
printf("R");
a--;
}
else if (b>)
{
printf("P");
b--;
}
else
{
printf("S");
c--;
}
}
}
printf("\n");
}
}
return ;
}
of B
C:
题意:
给你一个打印机打的小写字符组成的字符串,已知打印机会把w打成uu,m打成nn。问这个字符串可能的原串有几种。
分析:
很容易想到DP,因为就一个水的不行的线性DP,如果这个点和前面两个点都是u或者v就是前两项和,不然是前一项。不过有个wa点,出现w和m绝对NG!不过样例给出来了就是了。
代码:
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
long long dp[],flag,l,i;
int main()
{
string str;
getline(cin,str);
l=str.length();
flag=;
for (i=;i<l;i++)
{
if (str[i]=='m'||str[i]=='w') {flag=;break;}
}
if (flag==) cout<<<<endl;
else
{
dp[]=;
if ((str[]=='u'&&str[]=='u')||(str[]=='n'&&str[]=='n')) dp[]=;
else dp[]=;
for (i=;i<l;i++)
{
if ((str[i]=='u'&&str[i-]=='u')||(str[i]=='n'&&str[i-]=='n'))
dp[i]=(dp[i-]+dp[i-])%;
else dp[i]=dp[i-];
}
cout<<dp[l-]<<endl;
}
return ;
}
of C
D:
题意:
有n(0<n<=1e6)个城镇,每个坐标是(Xi,Yi),现在要给每个城镇通上电,对于城镇i,有两种方法,第一种自己发电,代价是Ci,第二种是连到一个有电的城市j,代价是(Ki+Kj)*Dij,Dij表示城镇i和城镇j之间的曼哈顿距离(横坐标差绝对值加纵坐标差绝对值)
分析:
构造一个虚拟的有电城市0,然后自己发电就是连接到0,从而变成了最小生成树,先生成所有边,然后kruskal一下。
代码:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
struct node
{
long long u,v,dis;
};
struct node d[];
long long x[],y[],c[],k[];
long long ans2[][],ans1[],f[];
using namespace std;
long long find(long long a)
{
if (a==f[a]) return a;
else return find(f[a]);
}
void combine(long long a,long long b)
{
f[find(a)]=find(b);
}
int cmp(struct node a,struct node b)
{
if (a.dis==b.dis&&a.u==b.u) return a.v<b.v;
else if (a.dis==b.dis) return a.u<b.u;
else return a.dis<b.dis;
}
int main()
{
long long n,i,m,res1,res2,sum,j,u,v;
scanf("%I64d",&n);
for (i=;i<=n;i++)
{
scanf("%I64d%I64d",&x[i],&y[i]);
}
m=;
for (i=;i<=n;i++)
{
scanf("%I64d",&c[i]);
m++;
d[m].dis=c[i];
d[m].u=;
d[m].v=i;
}
for (i=;i<=n;i++)
{
scanf("%I64d",&k[i]);
}
for (i=;i<=n-;i++)
for (j=i+;j<=n;j++)
{
m++;
d[m].dis=(abs(x[i]-x[j])+abs(y[i]-y[j]))*(k[i]+k[j]);
d[m].u=i;
d[m].v=j;
}
sort(d+,d+m+,cmp);
// for (i=1;i<=m;i++)
// {
// cout<<d[i].u<<" "<<d[i].v<<" "<<d[i].dis<<endl;
// }
for (i=;i<=n;i++)
{
f[i]=i;
}
res1=;
res2=;
sum=; for (i=;i<=m;i++)
{
u=d[i].u;
v=d[i].v;
if (find(u)!=find(v))
{
sum=sum+d[i].dis;
combine(u,v);
if (u==)
{
res1++;
ans1[res1]=v;
}
else
{
res2++;
ans2[res2][]=u;
ans2[res2][]=v;
}
}
if (res1+res2==n) break;
}
printf("%I64d\n",sum);
printf("%I64d\n",res1);
for (i=;i<res1;i++)
{
printf("%I64d ",ans1[i]);
}
printf("%I64d\n",ans1[res1]);
printf("%I64d\n",res2);
for (i=;i<=res2;i++)
{
printf("%I64d %I64d\n",ans2[i][],ans2[i][]);
}
return ;
}
of D
E:
题意:
有个10*10的方格,一个人从(10,1)蛇形(先横向前,再向上一格再横向后,再向上一格)向终点(1,1)前进。
每次前进都会丢一个1-6的骰子(几率相同),决定这次前进几步,如果到重点还有k步,投的大于k就会作废。
当然,不会这么简单,这个方格上存在一些梯子,可以竖着向上走一些长度。当你回合末停在一个梯子下的时候你可以选择向上爬(也可以不爬),下回合将在梯子顶的格子开始。需要注意的是,一个格子顶多有一个向上的梯子,不过可以有很多梯子通往这个格子。另爬梯子上来之后不能接着爬(毕竟回合末才能爬)
现在想尽可能快的走到终点(也就是中间选择爬不爬梯子将取决于那个更快),问总回合数的期望是多少。
分析:
概率DP,正着来的话,梯子的问题很难处理,不过每个格子只有一个向上的梯子,所以很容易想到倒退(概率DP常见手法)
需要注意的有:不是每一步都是除以6,有些点数不可能。
代码:
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
double dp[][];//[2];
//double dp2[12][12][2];
int a[][];
int c[][];
int h[];
int l[];
int main()
{
int i,j,k,n,t;
double sum;
for (i=;i<=;i++)
for (j=;j<=;j++)
{
cin>>a[i][j];
}
for (i=;i<=;i++)
for (j=;j<=;j++)
{
h[i*+j-]=i;
if (i%) l[i*-+j]=j;
else l[i*-+j]=-j;
c[h[i*+j-]][l[i*+j-]]=i*+j-;
}
//for (i=1;i<=10;i++)
//for (j=1;j<=10;j++)
//{
// cout<<c[i][j]<<" ";
// if (j==10) cout<<endl;
//}
dp[][]=;
for (k=;k<=;k++)
{
sum=;
n=;
for (t=;t<=;t++)
{
if (k>t)
{
if (a[h[k-t]][l[k-t]]!=)
{
if (dp[h[k-t]][l[k-t]]>dp[h[c[h[k-t]-a[h[k-t]][l[k-t]]][l[k-t]]]][l[c[h[k-t]-a[h[k-t]][l[k-t]]][l[k-t]]]])
sum=sum+dp[h[c[h[k-t]-a[h[k-t]][l[k-t]]][l[k-t]]]][l[c[h[k-t]-a[h[k-t]][l[k-t]]][l[k-t]]]];
else sum=sum+dp[h[k-t]][l[k-t]];
}
else sum=sum+dp[h[k-t]][l[k-t]];
n++;
}
else break;
}
dp[h[k]][l[k]]=(sum+)/n;
}
printf("%.10f\n", dp[][]);
return ;
}
of E
F:
题意:
t(最多100)组询问,每组询问为问区间[l,r],中间有多少组数a,b满足a+b=a^b(0<=l<=r<=1e9)
分析:
乍一看傻眼了,不过经验性的一个处理区间。
ans=solve(r,r)-solve(l-1,r)*2+solve(l,l);
solve(a,b)表示第一个数从1-a,第二个数从1-b
然后是按二进制位嘛,我下意识的想到的思路是这样的,找到两个数二进制数位中最高的那个位,
然后如果两个数这位都是1,那么,可以拆分成3个子情况递归,分别是
1:第一个数那位为1,第二个数那个位为0。
2:第一个数那位为0,第二个数那个位为1。
3:第一个数那位为0,第二个数那个位也为0。
然后我duang duang的敲了个代码,修了下过了样例。。。。。。。的前两个,然后第三个居然跳不出结果。咋回事呢?
我一拍脑袋,这玩意根本不降低多少复杂度,某些情况我可能反而天才的提升了复杂度(不愧是我)
怎么改进呢,很明显递归重复计算了很多相同的子情况,很容易想到记录下来空间换时间。
我意识到,递归的子情况无非是a变成a-(1<<i),min(a,(1<<i)-1),也就是要么是去掉首位,要么是变成111....1,除了1111...1,之外,其他都是取原a的从后往前的若干位。b同理。
所以用dp[i][j][k]表示状态,i是二进制位信息,从30-0,jk分别用0,1表示a,b变成啥状态。就是个结合位运算的dp。
代码:
#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
long long dp[][][];
long long solve(long n, long m)
{
long long a,b,c,d;
memset(dp,,sizeof(dp));
dp[][][] = ;
for (int i = ; i >= ; --i)
{
for (a = ; a <= ; a++)
for (b = ; b <= ; b++)
for (c = ; c <= ; c++)
for (d = ; d <= -c; d++)
if ((a|| c <= (n >> i & )) && (b || d <= (m >> i & )))
dp[i][a | (c < (n >> i & ))][b | (d < (m >> i & ))] += dp[i+][a][b];
}
return dp[][][];
}
int main()
{
long long i,j,t,k,l,r,ans;
cin>>t;
for (k=;k<=t;k++)
{
cin>>l>>r;
ans=solve(r+,r+)-solve(l,r+)*+solve(l,l);
cout<<ans<<endl;
}
return ;
}
of F
codeforces 597 div 2的更多相关文章
- Codeforces #344 Div.2
Codeforces #344 Div.2 Interview 题目描述:求两个序列的子序列或操作的和的最大值 solution 签到题 时间复杂度:\(O(n^2)\) Print Check 题目 ...
- Codeforces #345 Div.1
Codeforces #345 Div.1 打CF有助于提高做题的正确率. Watchmen 题目描述:求欧拉距离等于曼哈顿距离的点对个数. solution 签到题,其实就是求有多少对点在同一行或同 ...
- Codeforces Beta Round #27 (Codeforces format, Div. 2)
Codeforces Beta Round #27 (Codeforces format, Div. 2) http://codeforces.com/contest/27 A #include< ...
- Codeforces#441 Div.2 四小题
Codeforces#441 Div.2 四小题 链接 A. Trip For Meal 小熊维尼喜欢吃蜂蜜.他每天要在朋友家享用N次蜂蜜 , 朋友A到B家的距离是 a ,A到C家的距离是b ,B到C ...
- codeforces #592(Div.2)
codeforces #592(Div.2) A Pens and Pencils Tomorrow is a difficult day for Polycarp: he has to attend ...
- codeforces #578(Div.2)
codeforces #578(Div.2) A. Hotelier Amugae has a hotel consisting of 1010 rooms. The rooms are number ...
- codeforces #577(Div.2)
codeforces #577(Div.2) A Important Exam A class of students wrote a multiple-choice test. There are ...
- codeforces #332 div 2 D. Spongebob and Squares
http://codeforces.com/contest/599/problem/D 题意:给出总的方格数x,问有多少种不同尺寸的矩形满足题意,输出方案数和长宽(3,5和5,3算两种) 思路:比赛的 ...
- Codeforces Round #597 (Div. 2) D. Shichikuji and Power Grid
链接: https://codeforces.com/contest/1245/problem/D 题意: Shichikuji is the new resident deity of the So ...
随机推荐
- 【leetcode】1230.Toss Strange Coins
题目如下: You have some coins. The i-th coin has a probability prob[i] of facing heads when tossed. Ret ...
- ubuntu1604-Python35-cuda9-cudnn7-gpu-dockerfile
一,在某目录下有如下文件: -rw-r--r-- 1 root root 1643293725 9月 2 11:46 cuda_9.0.176_384.81_linux.run -rw-r--r-- ...
- sh_06_break
sh_06_break i = 0 while i < 10: # break 某一条件满足时,退出循环,不再执行后续重复的代码 # i == 3 if i == 3: break print( ...
- 【CF1243D&CF920E】0-1 MST(bfs,set)
题意:给定一张n个点的完全图,其中有m条边权为1其余为0,求最小生成树的权值和 n,m<=1e5 思路:答案即为边权为0的边连接的联通块个数-1 用set存图和一个未被选取的点的集合,bfs过程 ...
- mac卸载jdk
在本地gradle打包后,将war包部署到服务器,tomcat的localhost日志报这个错: 严重: Error configuring application listener of class ...
- [BZOJ4305]数列的GCD:莫比乌斯反演+组合数学
分析 一开始想的是对恰好\(k\)个位置容斥,结果发现对\(\gcd\)有些无从下手,想了想发现自己又sb了. 考虑对\(\gcd\)进行容斥处理,弱化条件,现在我们要求的是使\(\gcd\)是\(d ...
- Selenium 上手:Selenium扫盲区
Selenium 自述Selenium 是由Jason Huggins软件工程师编写的一个开源的浏览器自动化测试框架.主要用于测试自动化Web UI应用程序. Selenium 工作原理通过编程语言( ...
- 微信小程序打印json log
微信小程序中如果 res.data数据是一个json格式数据.console.log("===data===" + res.data);//如果这样打印出了是只会打印一个对象名称, ...
- RAC_单实例_DG 关于两端创建表空间数据文件路径不一致的问题注意点
RAC_单实例_DG 关于两端创建表空间数据文件路径不一致的问题注意点 主库SYS@orcl1>show parameter db_file_name_convert NAME TYPE VAL ...
- Go Int转string几种方式性能测试
Go Int转string几种方式性能测试 - 贤冰的博客 - CSDN博客 https://blog.csdn.net/flyfreelyit/article/details/79701577