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]的每个 ...
随机推荐
- Apache 服务器 首次访问特别慢的解决过程,php环境
一台服务器之前装的是java的tomcat apache 项目, 后面装了个phpstudy 在上面,访问php项目发现 浏览器首次打开网页需要7-8秒,打开成功后连续访问都很快,过一段时间访问又是7 ...
- 关于java中对BigDecimal加减乘除的基本用法
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数. 在实际应用中,需要对更大或者更小的数进 ...
- flask 第六篇 flask内置的session
Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...
- python接口自动化:python3.6中import Crypto.Hash报错的解决方案
一:问题 python3.6中算法加密引入包Crypto报错,即便安装了: pip install crypto pip install pycrypto pip install pycryptodo ...
- vue-cli构建的项目结构解析
参考: https://www.jianshu.com/p/32beaca25c0d
- Android studio 项目支持JNI方法
步骤: 1. build.gradle 配置如下,主要两项 ndk 和 sourceSets apply plugin: 'com.android.application' android { com ...
- Pyqt5-QtWidget的使用
QTableWidget是QTableViewer的子类 ,其中QTableViewer可以使用自定义的数据模型来显示内容(通过setModel ()来绑定数据源),而QTableWidget提供了一 ...
- Linux 查看登录用户信息 who & whoami
Linux 查看登录用户信息 who & whoami 在一台服务器上,同一时间往往会有很难多人同时登录. who 命令可以查看当前系统中有哪些人登录,以及他们都工作在哪个控制台上. 这样可以 ...
- ojdbc15-10.2.0.4.0.jar maven 引用报错 Dependency 'com.oracle:ojdbc15:10.2.0.4.0' not found
ojdbc15-10.2.0.4.0.jar maven 引用报错 问题现象 在 Maven 工程中引用 ojdbc15-10.2.0.4.0.jar 报错,报错信息:Dependency 'com. ...
- Python3命名规范
1.模块 模块尽量使用小写命名,首字母保持小写,尽量不要用下划线(除非多个单词,且数量不多的情况) # 正确的模块名 import decoder import html_parser # 不推荐的模 ...