A
solution:
每次只能在尾部操作,所以题目非常简单,只需要找到每个位置不相同的字符,长度不相同可以选择删除长的字符串,也可以选择添加短的字符串
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
int n,m,cnt = 0;
string s1,s2;
cin>>n>>m;
cin>>s1>>s2;
int minn = min(n , m);
for(int i=0;i<minn;i++)
{
if(s1[i] != s2[i]){
cnt++;
}
}
cout<<cnt + abs(n - m)<<endl;
return 0;
}B
solution:
第一次遇到三分的题目,,,
给你n个点,在x轴上找一点,求出该点到所有点的最大距离的最小值。
在x轴,没法证明这些点是单调的,二分不好做,用三分来找峰值
多写几个三分再来加点讲解
std
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 100005;
double a[maxn],b[maxn];
int n;
bool check(double mid)
{
double x = -10000.0,y = 10000.0;
for(int i=1;i<=n;i++)
{
if(fabs(b[i]) > mid)
return 0;
double z = sqrt(mid*mid - b[i]*b[i]);
if(a[i] - z > x)
x = a[i] - z;
if(a[i] + z < y)
y = a[i] + z;
}
return x - 1e-8 <= y;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&a[i],&b[i]);
double l = 0,r = 20000;
while(l <= r)
{
double mid = (l+r)/2;
if(check(mid))
r = mid - 1e-8;
else
l = mid + 1e-8;
}
printf("%.6lf\n",l);
return 0;
}C
solution:no solution,不大不小的模拟写哭了
D
solution:
一开始写成了搜索,写完测了几组样例有点不对,长记性了,还是先模拟模拟再写
其实只需要找到一个临界点,当选择闪现比每单位走1m的情况坏的时候,就不能再使用闪现
举个例子 :
牛可乐在-27,牛妹在5
第一次移动,牛可乐选择闪现到-3
第二次移动,牛可乐选择闪现到-3^(1/3)
第三次移动,如果接着使用闪现,永远无法到达正半轴,如果移动多个1m到达了正半轴,当前的点的三分之一次方无法到达一个比它大的数字上,所以一旦不使用闪现,接下来一定是一直以1m/s的方式移动
所以我们只要贪心的考虑每次移动的好坏
如果闪现的距离大于等于1m,且缩短距离就是用闪现
否则计算两人间的距离,累加到答案里,break
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 100005;
const double esp = 1e-8;
int main()
{
int t;
cin>>t;
while(t--)
{
int a,b;
scanf("%d %d",&a,&b);
double ans = 0;
double x = a,y = b;
double pi = 1.0/3.0;
while(1)
{
double z;
if(x < 0)
z = -pow(-x,pi);
else
z = pow(x,pi);
if(fabs(z - y) + 1.0 < fabs(x - y))
ans += 1.0,x = z;
else{
ans += fabs(x - y);
break ;
}
}
printf("%.9lf\n",ans);
}
return 0;
}E
solution:
没怎么学过博弈的算法,就找了找规律,考虑临界点,即必赢点或者必输点,
n = 奇数,先手必赢(先手每次只取1张牌),不再考虑奇数
n = 2,先手必输
n = 4,先手必输 所以结论是n为偶数先手必输?
n = 6,先手拿两张牌,n = 4,后手必输
n = 8,先手必输
n =10,先手拿2张牌,n = 8,后手必输
n =12,先手拿4张牌,n = 8,后手必输
n =14,先手拿6张牌,n = 8,后手必输
n =16,先手必输
规律出来了~
当n = 2的次幂,先手必输,否则先手必赢
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll n;
int flag = 0;
cin>>n;
for(ll i=2;i<=1e18;){
if(n < i){
break ;
}
if(n == i){
flag = 1;
break ;
}
i = i*2;
}
if(flag){
printf("Alice\n");
}else{
printf("Bob\n");
}
return 0;
}F
solution:
想必大家题目都理解的有点模糊,题目准确的说给你的x是每次RJ的时候会连续说几个“你能不能行啊”。然后给出你区间[l,r],让你输出这个区间所有可能的情况
这么一想是不是简单点了?由于有多次查询,我们只能预处理好前缀和
dp[i][0]表示说了i句话,且当前RJ了
dp[i][1]表示说了i句话,且当前AC了
状态转移方程:
dp[i][1] = dp[i-1][0] + dp[i-1][1]
dp[i][0] = dp[i-x][1]
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1e9 + 7;
const int maxn = 1000005;
ll dp[maxn][2];
int main()
{
int t,x,l,r;
scanf("%d",&x);
for(int i=1;i<=x;i++){
dp[i][0] = 1;
}
dp[x][1] = 1;
for(int i=x + 1;i<=maxn;i++){
dp[i][0] = (dp[i-1][0] + dp[i-1][1])%mod;
dp[i][1] = (dp[i-x][0] )%mod;
}
for(int i=1;i<=maxn;i++){
dp[i][0] = (dp[i][0] + dp[i][1] + dp[i-1][0])%mod;
}
scanf("%d",&t);
while(t--){
scanf("%d %d",&l,&r);
printf("%lld\n",(dp[r][0] - dp[l-1][0] +mod)%mod);
}
return 0;
}G
solution:
这道题真的是一道很好的bfs题
由于僵尸会在一个长为k的矩形中不断移动,但是每次移动都是有规律的,循环周期为2×(k-1),即每次移动,他们都会到达一个固定的位置,那么我们可以在bfs的向量里面添加时间这一向量,每次judge是否和僵尸的位置冲突,不断地bfs,直到队列为空或者走到终点结束
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 505;
int n,m,p,k;
char str[maxn],s[maxn][maxn];
int t[maxn][maxn][22];
ll vis[maxn][maxn][22];
int dx[] ={0 , 0 , -1 , 1};
int dy[] ={-1, 1 , 0 , 0};
struct node{
int x,y,z;
};
void init()
{
for(int i=1;i<=p;i++){
int x,y;
scanf("%d %d %s",&x,&y,str);
if(str[0] == 'R'){
for(int i=0;i<=k;i++)t[x][y+i][i]=1;
for(int i=k+1;i<2*k;i++)t[x][y+k-i+k][i]=1;
}
if(str[0] == 'U'){
for(int i=0;i<=k;i++)t[x-i][y][i]=1;
for(int i=k+1;i<2*k;i++)t[x-k+i-k][y][i]=1;
}
if(str[0] == 'D'){
for(int i=0;i<=k;i++)t[x+i][y][i]=1;
for(int i=k+1;i<2*k;i++)t[x+k-i+k][y][i]=1;
}
if(str[0] == 'L'){
for(int i=0;i<=k;i++)t[x][y-i][i]=1;
for(int i=k+1;i<2*k;i++)t[x][y-k+i-k][i]=1;
}
}
}
int solve(int x,int y,int z){
if(x < 1 || x > n || y < 1 || y > m || s[x][y] == '&' || t[x][y][z] == 1){
return 1;
}
return 0;
}
int main()
{
int x,y,z,sx,sy,tx,ty;
scanf("%d %d %d %d",&n,&m,&p,&k);k--;
for(int i=1;i<=n;i++){
scanf("%s",s[i] + 1);
for(int j=1;j<=m;j++){
if(s[i][j] == 'L'){sx = i, sy = j;}
if(s[i][j] == 'A'){tx = i, ty = j;}
for(int q=0;q<2*k;q++)
vis[i][j][q] = 1e18;
}
}
init();
vis[sx][sy][0] = 0;
queue<node> q;
q.push(node{sx,sy,0});
while(!q.empty())
{
node now = q.front();q.pop();
x = now.x,y = now.y,z = now.z;
for(int i=0;i<4;i++){
int xx = x + dx[i];
int yy = y + dy[i];
int zz = (z + 1)%(2*k);
if(solve(x,y,z)){
continue ;
}
if(vis[xx][yy][zz] > vis[x][y][z] + 1){
vis[xx][yy][zz] = vis[x][y][z] + 1;
q.push(node{xx,yy,zz});
}
}
}
ll ans = 1e18;
for(int i=0;i<2*k;i++){
ans = min(ans , vis[tx][ty][i]);
}
if(ans >= 1e18){
printf("Oh no\n");
}else{
printf("%lld\n",ans);
}
return 0;
}
H
solution:
从进制转换的角度不难发现,字符串是26进制,而其hash值为10进制,那么就很简单了,先将字符串S的hash值k算出来,因为S′与其取模相同且 字典序最小,那么 k′=k+mod,然后将其转换为26进制输出
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
string s;
int mod ;
while(cin>>s>>mod)
{
int cnt = 0;
for(int i=0;i<6;i++){
cnt = cnt*26 + (s[i] - 'a');
}
cnt += mod;
for(int i=5;i>=0;i--)
{
s[i] = 'a' + (cnt%26);
cnt /= 26;
}
if(cnt){
cout<<"-1"<<endl;
}else{
cout<<s<<endl;
}
}
return 0;
}I
solution:
只有一个坑,就是可能会存在并列的人数
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int a[20];
int main()
{
int n , m ,cnt = 0;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int ans = a[9];
sort(a+1,a+1+n);
int pre = a[n-2];
if(ans >= pre){
printf("Yes\n");
return 0;
}
if(ans*10 - 8*m >= 0){
printf("Yes\n");
return 0;
}
printf("No\n");
return 0;
}J
solution:
球的内接正n多边形边长等于 2rsin(180/n),这里记得将180换成pai
std:
#include
using namespace std;
#define ll long long
int main()
{
int n,r;
int x,y;
cin>>n>>r>>x>>y;
int l = min(x,y);
int rr = max(x,y);
int z = min(rr-l , n-rr+l);
double rrr = (double)r;
double esp = acos(-1.0);
double cnt = (2.000000*rrr)*(sin(esp/((double)n)));
double ans = cnt*((double)z);
printf("%.6lf\n",ans);
return 0;
}
京公网安备 11010502036488号