思路:模拟从(0,0)到每个位置需要哪些操作,如果总共需要4种操作就输出NO。
// Problem: A. Distinct Buttons
// Contest: Codeforces - Pinely Round 3 (Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1909/problem/0
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pairpl;
priority_queue, greater >mi;//小根堆
priority_queue ma;//大根堆
LL gcd(LL a, LL b){
return b > 0 ? gcd(b , a % b) : a;
}
LL lcm(LL a , LL b){
return a / gcd(a , b) * b;
}
int n , m;
vectora(N , 0);
void init(int n){
for(int i = 0 ; i <= n ; i ++){
a[i] = 0;
}
}
void solve()
{
cin >> n;
int flag[4] = {0 , 0 , 0 , 0};
for(int i = 0 ; i < n ; i ++){
int x , y;
cin >> x >> y;
if(x < 0){
flag[0] = 1;
}
else if(x > 0){
flag[1] = 1;
}
if(y < 0){
flag[2] = 1;
}
else if(y > 0){
flag[3] = 1;
}
}
int cnt = 0;
for(int i = 0 ; i < 4 ; i ++){
cnt += flag[i];
}
if(cnt <= 3){
cout <<"Yes\n";
}
else{
cout <<"NO\n";
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout.precision(10);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}
思路:比较有意思的题目,可以发现k取2的倍数即可。证明如下:将所有数变为二进制表示,那么某个数模2的结果即二进制最后一位,模4的结果即二进制的后两位...如此类推。
由于题目必然存在解,也就是说数组不可能全相等。既然不可能全相等,那一定存在整个数组某一位存在1和0。因此k取2的倍数必然能够满足题意。
// Problem: B. Make Almost Equal With Mod
// Contest: Codeforces - Pinely Round 3 (Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1909/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
#define int long long
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 1e18;
typedef pairpl;
priority_queue, greater >mi;//小根堆
priority_queue ma;//大根堆
LL gcd(LL a, LL b){
return b > 0 ? gcd(b , a % b) : a;
}
LL lcm(LL a , LL b){
return a / gcd(a , b) * b;
}
int n , m;
vectora(N , 0);
void init(int n){
for(int i = 0 ; i <= n ; i ++){
a[i] = 0;
}
}
void solve()
{
cin >> n;
int cnt1 = 0 , cnt0 = 0;
for(int i = 0 ; i < n ; i++){
cin >> a[i];
}
for(int j = 2 ; j <= llinf ; j *= 2){
setst;
for(int i = 0 ;i < n ; i ++){
st.insert(a[i] % j);
}
if(st.size() == 2){
cout << j << endl;
return;;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout.precision(10);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}
思路:首先想到对l,r,c数组进行排序。可以发现,无论如何排序,所有区间长度之和是不会改变的。因此要让权值之和最小,需要让小的区间尽可能小。即对于任意而言,为最靠近它的元素。而从小到大的处理可以保证不会影响到后面的数。
// Problem: C. Heavy Intervals
// Contest: Codeforces - Pinely Round 3 (Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1909/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
#define int long long
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pairpl;
priority_queue, greater >mi;//小根堆
priority_queue ma;//大根堆
LL gcd(LL a, LL b){
return b > 0 ? gcd(b , a % b) : a;
}
LL lcm(LL a , LL b){
return a / gcd(a , b) * b;
}
int n , m;
vectora(N , 0);
void init(int n){
for(int i = 0 ; i <= n ; i ++){
a[i] = 0;
}
}
void solve()
{
cin >> n;
int l[n] , r[n] , c[n];
for(int i = 0 ; i < n ; i ++)
cin >> l[i];
for(int i = 0 ; i < n ; i ++)
cin >> r[i];
for(int i = 0 ; i < n ; i ++)
cin >> c[i];
sort(c , c + n);
sort(l , l + n);
sort(r , r + n);
int pre[n];
stackst;
int ll = 0;
int ans = 0;
for(int i = 0 ; i < n ;i ++){
while(ll < n && r[i] > l[ll]){
st.push(l[ll]);
ll++;
}
int x = st.top();
st.pop();
pre[i] = r[i] - x;
}
sort(pre , pre + n);
for(int i = 0 ; i < n ; i ++){
ans += pre[i] * c[n - i - 1];
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout.precision(10);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}
思路:假设最终所有数为,对于而言,需要操作次以后能变成ans,需要满足。
转换一下后得到
即成立的条件为:
为了方便解释,假设所有数都大于。想要操作数最小,即需要最大。可以发现,最终的的最大值为。求出gcd之后再带回原式子求出操作数即可。相反所有数都小于也是一样的操作。需要注意存在数等于时,需要所有数都等于,否则输出-1。
// Problem: D. Split Plus K
// Contest: Codeforces - Pinely Round 3 (Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1909/problem/D
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
#define int long long
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pairpl;
priority_queue, greater >mi;//小根堆
priority_queue ma;//大根堆
LL gcd(LL a, LL b){
return b > 0 ? gcd(b , a % b) : a;
}
LL lcm(LL a , LL b){
return a / gcd(a , b) * b;
}
int n , m;
vectora(N , 0);
void init(int n){
for(int i = 0 ; i <= n ; i ++){
a[i] = 0;
}
}
void solve()
{
// x + tk = (t + 1) * ans
// x - ans = t(ans - k)
// ans - k < 0 ??
// (x - ans / ans - k ) = t // ans 越大越好
cin >> n >> m;
for(int i = 0 ; i < n ; i++)
cin >> a[i];
sort(a.begin() , a.begin() + n);
for(int i = 0 ; i < n ; i ++){
if(a[0] < m && a[i] >= m){
cout << -1 << endl;
return;
}
}
for(int i = 0 ; i < n ; i ++){
a[i] -= m;
}
int ans = 0;
for(int i = 0 ; i < n ; i ++){
ans = gcd(ans , abs(a[i]));
}
int out = 0;
if(a[0] == 0 && a[n - 1] != 0 || a[0] != 0 && a[n - 1] == 0){
cout << -1 << endl;
return;
}
else if(ans == 0){
cout << 0 << endl;
return;
}
for(int i = 0 ; i < n ; i ++){
if(a[i] >= 0){
out += (a[i] - ans) / ans ;
}
else{
out += (a[i] + ans) / -ans;
}
}
cout << out << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout.precision(10);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}
// Problem: E. Multiple Lamps
// Contest: Codeforces - Pinely Round 3 (Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1909/problem/E
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pairpl;
priority_queue, greater >mi;//小根堆
priority_queue ma;//大根堆
LL gcd(LL a, LL b){
return b > 0 ? gcd(b , a % b) : a;
}
LL lcm(LL a , LL b){
return a / gcd(a , b) * b;
}
int n , m;
vectora(N , 0);
void init(int n){
for(int i = 0 ; i <= n ; i ++){
a[i] = 0;
}
}
int dp[(1 << 20)][20];
void solve()
{
cin >> n >> m;
vectoru(m) , v(m);
for(int i = 0 ; i < m ; i ++){
cin >> u[i] >> v[i];
}
if(n >= 20){
cout << n << endl;
for(int i = 1 ; i <= n ; i ++){
cout << i <<" ";
}
cout << endl;
}
else{
int ans = -1;
auto check = [&](int s){
int x = s;
if(__builtin_popcount(s) > n / 5){
return;
}
if(dp[s][n] != 0){
s = dp[s][n];
}
else{
for(int i = 1 ; i <= n ; i ++){
if(s >> i & 1){
for(int j = 2 * i; j <= n ; j += i){
s ^= (1 << j);
}
}
}
dp[x][n] = s;
}
for(int i = 0 ; i < m ; i ++){
if(((s >> u[i]) & 1) && !((s >> v[i]) & 1)){
return;
}
}
ans = s;
};
for (int x = 1; x <= n; x++) {
check(1 << x);
for (int y = 1; y < x; y++) {
check(1 << x | 1 << y);
for (int z = 1; z < y; z++) {
check(1 << x | 1 << y | 1 << z);
}
}
}
if(ans == -1){
cout << -1 << endl;
}
else{
cout << __builtin_popcount(ans) << endl;
for (int i = 1; i <= n; i++) {
if (ans >> i & 1) {
cout << i << " ";
}
}
cout << endl;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout.precision(10);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}
思路:(小技巧之你懂暴力枚举么)当把所有灯全部按一遍时,所有完全平方数会亮着,也就是共有个灯还留着。会发现大部分情况之下 ,只有时不满足。于是的情况就可以暴力枚举了。
由于数据很小,因此可以考虑状压来解决。枚举每一种可能情况,然后求出该种情况之下需要按哪些灯,再看是否满足规则即可。
// Problem: E. Multiple Lamps
// Contest: Codeforces - Pinely Round 3 (Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1909/problem/E
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pairpl;
priority_queue, greater >mi;//小根堆
priority_queue ma;//大根堆
LL gcd(LL a, LL b){
return b > 0 ? gcd(b , a % b) : a;
}
LL lcm(LL a , LL b){
return a / gcd(a , b) * b;
}
int n , m;
vectora(N , 0);
void init(int n){
for(int i = 0 ; i <= n ; i ++){
a[i] = 0;
}
}
int dp[(1 << 20)][20];
void solve()
{
cin >> n >> m;
vectoru(m) , v(m);
for(int i = 0 ; i < m ; i ++){
cin >> u[i] >> v[i];
}
if(n >= 20){
cout << n << endl;
for(int i = 1 ; i <= n ; i ++){
cout << i <<" ";
}
cout << endl;
}
else{
int ans = -1;
auto check = [&](int s){
int x = s;
if(__builtin_popcount(s) > n / 5){
return;
}
if(dp[s][n] != 0){
s = dp[s][n];
}
else{
for(int i = 1 ; i <= n ; i ++){
if(s >> i & 1){
for(int j = 2 * i; j <= n ; j += i){
s ^= (1 << j);
}
}
}
dp[x][n] = s;
}
for(int i = 0 ; i < m ; i ++){
if(((s >> u[i]) & 1) && !((s >> v[i]) & 1)){
return;
}
}
ans = s;
};
for (int x = 1; x <= n; x++) {
check(1 << x);
for (int y = 1; y < x; y++) {
check(1 << x | 1 << y);
for (int z = 1; z < y; z++) {
check(1 << x | 1 << y | 1 << z);
}
}
}
if(ans == -1){
cout << -1 << endl;
}
else{
cout << __builtin_popcount(ans) << endl;
for (int i = 1; i <= n; i++) {
if (ans >> i & 1) {
cout << i << " ";
}
}
cout << endl;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout.precision(10);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}