Codeforces 817+818(A~C)
(点击题目即可查看原题)
题意:给出起点和终点,每次移动只能从 (a,b)移动至(a+x,b+y) , (a+x,b-y) , (a-x,b+y) , (a-x,b-y) 四个位置,问能否从终点走到起点
思路:先计算出起点和终点的横纵坐标之差 X,Y, 首先必须满足 X%x == 0 && Y % y == 0 ,这样才可以走到和终点一样的位置,后计算 X/x . Y/y ,我们注意到如果 X/x != Y/y 那么就可能无法用到达,不过,我们可以在两次运动过程中只走X方向或者Y方向,也就是如果 abs( X/x - Y/y ) % 2 == 0 ,那么也是可以到达的;此外的情况都是无法到达的。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip>
#define bug cout << "**********" << endl
#define show(x,y) cout<<"["<<x<<","<<y<<"] "
//#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = 1e6 + ;
const int Max = 1e5 + ; int s_x, s_y, e_x, e_y;
int x, y; int main()
{
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
while (scanf("%d%d%d%d", &s_x, &s_y, &e_x, &e_y) != EOF)
{
scanf("%d%d", &x, &y);
if (abs(s_x - e_x) % x == && abs(s_y - e_y) % y ==
&& abs(abs(s_x - e_x) / x - abs(s_y - e_y) / y) % == )
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return ;
}
817A
题意:给出n个数a[1] ~ a[n] ,求使得 a[i] * a[j] * a[k] 最小的组合 (i,j,k) 有多少个,其中 i , j , k 互不相等。
思路:摆明了让你求最小的三个值的个数,求出最小值,,次小值的,,第三小值的个数,然后根据以下规律凑成组合并输出个数,emmm,组合数
1)最小的有三个以上,那么三个均有最小的组成
2)如果最小的只有两个,那么最小的肯定要选,所以由两个最小和一个次小组成
3)最小的只有一个,次小的有两个以上,那么由一个最小和两个次小组成
4)最小和次小都只有一个,那么由最小,次小,第三小各选一个组成
输出对应的组合数即可(博主用自己的组合数板子写了第一发,结果范围不够,WA了,不过这个地方不需要用组合数板子来写,因为计算次数最多4次,直接算就好)
#include<iostream>
#include<cstdio>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip>
#define bug cout << "**********" << endl
#define show(x,y) cout<<"["<<x<<","<<y<<"] "
//#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + ;
const int Max = 1e5 + ; int n;
int a[Max];
map<int, int>mp; //记录每个数字出现的次数 int main()
{
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
while (scanf("%d", &n) != EOF)
{
mp.clear();
for (int i = ;i <= n;i++)
{
scanf("%d", a + i), mp[a[i]]++;
} sort(a + , a + + n);
int tot = unique(a + , a + + n) - a - ; //排序并去重,使得a[1]~a[3]对应最小的三个数 if (mp[a[]] >= ) //最小的有三个以上,那么三个均有最小的组成
{
printf("%d\n",mp[a[]] * (mp[a[]] - ) * (mp[a[]] -) / );
}
else if (mp[a[]] == ) //如果最小的只有两个,那么最小的肯定要选,所有由两个最小和一个次小组成
{
printf("%d\n", mp[a[]]);
}
else if (mp[a[]] == && mp[a[]] >= ) //最小的只有一个,次小的有两个以上,那么有一个最小和两个次小组成
{
printf("%d\n", mp[a[]] * (mp[a[]] - ) / );
}
else //最小和次小都只有一个,那么最小,次小,第三小各选一个
{
printf("%d\n",mp[a[]]);
}
} return ;
}
817B
题意:给出两个数n,s,问在 [1,n] 范围内有多少个数 满足 x 和 x 的各个位上的数之和 大于s ( x 属于 [1,n])
思路:打表找规律,发现从某一个数开始,后面的数都是满足条件的,那么就简单了,二分第一个满足的数,其后的数就都满足条件了
#include<iostream>
#include<cstdio>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip> #define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + ;
const int Max = 1e5 + ; ll n, m; int main()
{
#ifdef LOCAL
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
while (scanf("%lld%lld", &n, &m) != EOF)
{
ll l = , r = n;
while (l <= r)
{
ll sum = ;
ll mid = (l + r) >> ;
ll k = mid;
while (k)
{
sum += k % ;
k /= ;
}
if (abs(mid - sum) < m)
{
l = mid + ;
}
else
{
r = mid - ;
}
}
printf("%lld\n", n - l + );
}
return ;
}
817C
818A Diplomas and Certificates
题意:有n个人,需要为他们分两种奖品,其中一种奖品的数量必须是另一种奖品数量的k倍,每个人只能分到一个奖品,并且有奖品的人数不得超过n/2个,输出两种奖品的数量和没有得奖的人数
思路:一个简单的公式 x + k * x <= n/2 ,得到的x向下取整,输出 x , k * x , n - (k+1)*x 就OK了。
#include<iostream>
#include<cstdio>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip>
#define bug cout << "**********" << endl
#define show(x,y) cout<<"["<<x<<","<<y<<"] "
//#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + ;
const int Max = 1e5 + ; ll n, k; int main()
{
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
while (scanf("%lld%lld", &n, &k) != EOF)
{
ll x = (n/) / (k + );
printf("%lld %lld %lld\n", x, k*x, n - (k + )*x);
}
return ;
}
818A
题意:有n个人围成环玩游戏,每个人的位置按顺时针从1~n排列,一共m轮,每轮选出一个领导者,用l[i]表示第i轮的领导是谁,每个人当领导的时候,他会选择他后面第a[i]个人担任下一轮的领导,并且a[i] 只能是 1 ~ n 中的值,并且每个人的a[i] 都不一样,换句话说,n个人的a[i]组成 1 ~ n ,给出了n,m, l[i],求a[i],如果不存在,输出-1
思路:我们注意到,每一轮的领导者都是上一轮领导后的第a[i]位,那么 a[i-1] = l[i] - l[i-1] ,又因为n个人排成环,所以当 l[i] < l[i-1] 的时候,a[i-1] = l[i] + n - l[i-1],这样就可以求出a[i]了,对于不确定的a[i],我们给其一个没有出现过的数当成这个数的a[i]即可。而如果某两个人的a[i]相同,那么就不存在,输出-1
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip> #define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + ;
const int Max = 1e5 + ; int n, m;
int leader[Max]; //记录第i个领导者的位置
int a[Max]; //每次移动距离
int vis[Max]; int main()
{
#ifdef LOCAL
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
while (scanf("%d%d", &n, &m) != EOF)
{
memset(a, -, sizeof(a));
memset(vis, , sizeof(vis));
bool ok = true; scanf("%d", leader + );
for (int i = ; i <= m; i++)
{
scanf("%d", leader + i);
int temp = ;
int add = ;
if(leader[i] <= leader[i-])
{
add += n;
}
temp = leader[i] + add - leader[i-]; if (a[leader[i - ]] == - || a[leader[i - ]] == temp) //同一个人同一个a[i]没有问题
{
if (vis[temp] && a[leader[i - ]] == -) //不同的人有相同的a[i]
{
ok = false;
}
else
{
a[leader[i - ]] = temp;
vis[temp] = true;
}
}
else
{
ok = false;
}
} if (!ok)
{
printf("-1\n");
}
else
{
for (int i = ; i <= n; i++)
{
if (a[i] != -)
{
printf("%d ", a[i]);
}
else
{
for (int j = ; j <= n; j++)
{
if (!vis[j])
{
printf("%d ", j);
vis[j] = true;
break;
}
}
}
}
printf("\n");
}
}
return ;
}
818B
题意:在一个 n * m 的房间内,有 d 个沙发,每个沙发占两个单位面积,我们将(x,y)视作一单位面积,给出每个沙发的位置x1,y1,x2,y2 ,代表这个沙发的位置为 (x1,y1),(x2,y2),保证没有两个及以上的沙发占用同一个位置,最后给出我们需要的沙发的信息cntL,cntR,cntB,cnrT,分别代表我们需要找的沙发的 左边沙发的个数,右边沙发的个数,底部沙发的个数,顶部沙发的个数,注意,只要两个沙发A,B,满足 A.x < B.x ,x = x1,x2,那么A就在B的左边,如果 A.y < B.y ,y = y1,y2,那么A在B的顶部,也就是说,y值大的在底部,问满足这个要求的沙发的编号,如果不存在,输出-1
思路:思路很简单,不过很多细节需要注意,具体方法如下
当前沙发左边的沙发数:所有左边界小于当前沙发右边界的沙发总数,
1、如果找到第一个大于等于当前沙发右边界的,
1) 如果当前沙发左右边界相等,那么此前的都是
2)如果不相等,减去自身;
2、如果没有大于等于当前沙发右边界的,那么此前所有的沙发都是的
当前沙发右边的沙发数:所有右边界大于当前沙发左边界的沙发总数,
1、如果找到第一个大于当前沙发左边界的,
1)如果当前沙发左右边界相等,那么此后的都是
2)如果不相等,减去自身
2、如果没有找到大于当前沙发左边界的,那么就没有
当前沙发底部的沙发数:所有上边界大于当前沙发下边界的沙发总数
1、找到第一个大于当前沙发下边界的沙发,
1) 如果上下边界相同,那么此后的都是
2)如果不相等,减去自身
2、如果没有大于当前沙发下边界的沙发,那么就没有
当前沙发顶部的沙发数:所有下边界小于当前沙发上边界的沙发总数
1、如果找到第一个大于等于当前沙发上边界的沙发
1) 如果上下边界相同,那么此前的都是
2)如果不相等,那么减去自身
2、如果没有大于等于当前沙发上边界的沙发,那么全都是
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip> #define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + ;
const int Max = 1e5 + ; struct Node
{
int x1, y1, x2, y2;
} node[Max]; int d, n, m;
int cntL, cntR, cntT, cntB;
int R[Max], L[Max], T[Max], B[Max]; //记录四个边界 int main()
{
#ifdef LOCAL
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
while (scanf("%d%d%d", &d, &n, &m) != EOF)
{
for (int i = ; i <= d; i++)
{
scanf("%d%d%d%d", &node[i].x1, &node[i].y1, &node[i].x2, &node[i].y2);
if (node[i].x1 > node[i].x2)
swap(node[i].x1, node[i].x2);
if (node[i].y1 > node[i].y2) //大数为底部
swap(node[i].y1, node[i].y2);
L[i] = node[i].x1; //记录每个沙发的左边界
R[i] = node[i].x2; //记录每个沙发的右边界
B[i] = node[i].y1; //记录每个沙发的下边界
T[i] = node[i].y2; //记录每个沙发的上边界,值大的为上边界
//cout << "L: " << L[i] << " R: " << R[i] << " B: " << B[i] << " T: " << T[i] << endl;
}
scanf("%d%d%d%d", &cntL, &cntR, &cntT, &cntB);
sort(R + , R + + d);
sort(L + , L + + d);
sort(B + , B + + d);
sort(T + , T + + d); //均升序排序
int id = -;
for (int i = ; i <= d; i++) //枚举沙发
{
int ansL = lower_bound(L + , L + + d, node[i].x2) - L;
if (ansL == d + ) //没有找到大于等于当前沙发右边界的沙发
{
ansL = d - ;
}
else
{
ansL--;
if (node[i].x1 != node[i].x2) //排除自身左边界的影响
{
ansL--;
}
}
//cout <<"ansL: "<<ansL<<endl;
if (ansL != cntL)
continue;
/**********************************************/
int ansR = upper_bound(R + , R + + d, node[i].x1) - R;
if (ansR == d + ) //没有找到大于当前沙发左边界的沙发,那么都是
{
ansR = ;
}
else
{
ansR = d - ansR + ;
if (node[i].x1 != node[i].x2) //排除自身右边界的影响
{
ansR--;
}
}
//cout <<"ansR: "<<ansR<<endl;
if (ansR != cntR)
continue;
/**********************************************/
int ansB = upper_bound(T + , T + + d, node[i].y1) - T;
if (ansB == d + ) //没有找到大于当前沙发下边界的沙发,那么没有
{
ansB = ;
}
else
{
ansB = d - ansB + ;
if (node[i].y1 != node[i].y2)
{
ansB--;
}
}
//cout <<"ansB: "<<ansB<<endl;
if (ansB != cntB)
continue;
/**********************************************/
int ansT = lower_bound(B + , B + + d, node[i].y2) - B;
if (ansT == d + )
{
ansT = d - ;
}
else
{
ansT--;
if (node[i].y1 != node[i].y2)
{
ansT--;
}
}
//cout <<"ansT: "<<ansT<<endl;
if (ansT != cntT)
continue;
/**********************************************/
id = i;
break;
}
printf("%d\n", id);
}
return ;
} //当前沙发左边的沙发数:所有左边界小于当前沙发右边界的沙发总数,
//1、如果找到第一个大于等于当前沙发右边界的,
//1) 如果当前沙发左右边界相等,那么此前的都是,2)如果不相等,减去自身;
//2、如果没有大于等于当前沙发右边界的,那么此前所有的沙发都是的 //当前沙发右边的沙发数:所有右边界大于当前沙发左边界的沙发总数,
//1、如果找到第一个大于当前沙发左边界的,
//1)如果当前沙发左右边界相等,那么此后的都是,2)如果不相等,减去自身
//2、如果没有找到大于当前沙发左边界的,那么就没有 //当前沙发底部的沙发数:所有上边界大于当前沙发下边界的沙发总数
//1、找到第一个大于当前沙发下边界的沙发,
//1) 如果上下边界相同,那么此后的都是,2)如果不相等,减去自身
//2、如果没有大于当前沙发下边界的沙发,那么就没有 //当前沙发顶部的沙发数:所有下边界小于当前沙发上边界的沙发总数
//1、如果找到第一个大于等于当前沙发上边界的沙发
//1) 如果上下边界相同,那么此前的都是,2)如果不相等,那么减去自身
//2、如果没有大于等于当前沙发上边界的沙发,那么全都是
818C
Codeforces 817+818(A~C)的更多相关文章
- Codeforces Round #581(Div. 2)
Codeforces Round #581(Div. 2) CF 1204 A. BowWow and the Timetable 题解:发现,$4$的幂次的二进制就是一个$1$后面跟偶数个$0$. ...
- Codeforces A. Playlist(暴力剪枝)
题目描述: Playlist time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
- Codeforces 840C 题解(DP+组合数学)
题面 传送门:http://codeforces.com/problemset/problem/840/C C. On the Bench time limit per test2 seconds m ...
- Educational Codeforces Round 29(6/7)
1.Quasi-palindrome 题意:问一个字符串(你可以添加前导‘0’或不添加)是否是回文串 思路:将给定的字符串的前缀‘0’和后缀‘0’都去掉,然后看其是否为回文串 #include< ...
- Codeforces Round #334(div.2)(新增不用二分代码) B
B. More Cowbell time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- Codeforces 327A-Flipping Game(暴力枚举)
A. Flipping Game time limit per test 1 second memory limit per test 256 megabytes input standard inp ...
- Codeforces 488D Strip (set+DP)
D. Strip time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...
- Codeforces 1195E. OpenStreetMap (单调队列)
题意:给出一个n*m的矩形.询问矩形上所有的a*b的小矩形的最小值之和. 解法:我们先对每一行用单调栈维护c[i][j]代表从原数组的mp[i][j]到mp[i][j+b-1]的最小值(具体维护方法是 ...
- CodeForces 407C 组合数学(详解)
题面: http://codeforces.com/problemset/problem/407/C 一句话题意:给一个长度为n的序列g,m次操作,每次操作(l,r,k)表示将g[l]~g[r]的每个 ...
随机推荐
- JavaWeb_(Hibernate框架)Hibernate配置文件hibernate.cfg.xml
hibernate.cfg.xml配置文件——链接数据库 hibernate.cfg.xml一定要配置在/src文件目录下 --数据库驱动,url,用户名,密码 --方言org.hibernate.d ...
- 移动平台对meta标签的定义
一.meta 标签分两大部分:HTTP 标题信息(http-equiv)和页面描述信息(name). 1.http-equiv 属性的 Content-Type 值(显示字符集的设定) 说明:设定页面 ...
- SpringBoot2.X&Prometheus使用
1.启动Prometheus [root@ip101 prometheus-2.12.0.linux-amd64]# pwd /opt/app/prometheus-2.12.0.linux-amd6 ...
- websphere启动报:Could not resolve placeholder 'hibernate.hbm2ddl.auto' in string value "${hibernate.hbm2ddl.auto}"
websphere启动报/WEB-INF/applicationContext-orm- hibernate.xml]: Could not resolve placeholder 'hibernat ...
- CentOS7 磁盘管理
一.磁盘查看 查看所有磁盘 ll /dev/sd* 不带数字的为磁盘,带数字的为磁盘的分区 查看所有磁盘的分区情况 fdisk -l 结果 WARNING: fdisk GPT support is ...
- selenium_java
等待 页面全加载 ChromeOptions options=new ChromeOptions(); /** *(1) NONE: 当html下载完成之后,不等待解析完成,selenium会直接返回 ...
- tfserving 调用deepfm 并预测 java 【参考】
https://blog.csdn.net/luoyexuge/article/details/79941565?utm_source=blogxgwz8 首先是libsvm格式数据生成java代码, ...
- NAT(地址转换技术)详解
目录 NAT产生背景ip地址基础知识NAT技术的工作原理和特点静态NAT动态NATNAT重载(经常应用到实际中)NAT技术的优缺点优点缺点NAT穿越技术应用层网关(ALG)ALG的实际应用NAT技术的 ...
- C++异常实现机制
1.C函数的调用和返回 要理解C++异常机制实现之前,首先要了解一个函数的调用和返回机制,这里面就要涉及到ESP和EBP寄存器.我们先看一下函数调用和返回的流程. 下面是按调用约定__stdcall ...
- ajax post 请求
$(".login_btn").click(function(){ if($(".user_").val()=="admin"&&a ...