第一天打卡 Codeforces Round #569 (Div. 2)
为了能早日上紫名,特此开一个记录我每天刷题记录的。
除了每日专题以外,每天一套cf,开着虚拟参赛做。
A
水题
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int n;
int main()
{
n = read();
int sum = 0; int len = 2 * n - 1;
upd(i, 1, n - 2)sum += i;
cout << (len*len-((n-1)*(n-1) - sum)*4) << endl;
return 0;
}
B
这道题wa了7次。。一开始用感觉做的,后来稍微推导了一下。
不应该啊不应该。
题意:给出一个序列,需在能对序列的某一个值进行操作ai=-ai-1,问最大乘积。
解:
可以看出,只看绝对值的话,那么我们可以发现,只有正数变为负数会有正收益。那我们不管,先把全部序列变为负数再说。
如果序列长度是偶数,那么乘积为正数,符合题意。
如果序列长度是奇数,乘积为负数,不符合题意。
那么我们就需要变一个负数为正数。
假定该数字为a。(a<0)
假定一个存在的数字b,|a|<|b|
那么变a的代价为a-1sum
变b的代价为b-1 sum2。
去掉相同的部分,变为(a-1)b,(b-1)a 所以我们变化绝对值大的数字。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
struct node {
int val, pos;
bool operator < (const node &a)const {
return val < a.val;
}
}b[N];
int a[N];
int n;
int ans[N];
int main()
{
n = read();
upd(i, 1, n)a[i] = read(),b[i].val=a[i],b[i].pos=i;
upd(i, 1, n)
if (b[i].val >= 0)b[i].val = -b[i].val - 1;
sort(b+1, b + n+1);
if (n %2)
{
b[1].val = -b[1].val - 1;
}
upd(i, 1, n)ans[b[i].pos] = b[i].val;
upd(i, 1, n)cout << ans[i] << " ";
}
c:给一个双端队列,每次取出前两个,a,b,把大的数字放在首,小的放在尾。
问第m次操作的a和b。
看了题目就秒掉了。。我感觉比b简单多了。。。
很明显这种题目老套路,先找规律,因为m很大。
果然,看题目给的样例就发现当max移到队首的时候,后面n-1个数字将会无限循环。
故我们判断一下m,是max移到队首之前还是之后,分开讨论即可。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int n, q;
const int N = 1e5 + 10;
int a[N];
deque<int>dq;
int a2[N];
pair<int, int>p[N];
int main()
{
n = read(), q = read();
int maxn = -1, pos = -1;
up(i, 0, n)
{
a[i] = read();
if (maxn < a[i])maxn = a[i], pos = i;
dq.push_back(a[i]);
}
int num = 1;
int cnt = 0;
while (1)
{
int a = dq.front();
if (a == maxn)break;
dq.pop_front();
int b = dq.front();
dq.pop_front();
p[cnt++] = make_pair(a, b);
if (a < b)swap(a, b);
dq.push_front(a);
dq.push_back(b);
num++;
if (a == maxn)break;
}
ll m = 0;
up(i, 0, n)
a2[i] = dq.front(), dq.pop_front();
//cout << num << endl;
while (q--)
{
m = read();
if (m < num)
{
printf("%d %d", p[m-1].first,p[m-1].second);
}
else {
ll temp = m - num;
int mod = temp % (n - 1);
printf("%d %d", a2[0], a2[mod + 1]);
}
cout << endl;
}
return 0;
}
d:找规律
给出一个点阵,每次能随意走,但是保证两点之间的路线,即线段,没有完全一样的(包括方向)即可。
一开始看题目的意思我以为是找对称关系,一个往上走,对应一半往下走发现做不出来。
再仔细思考一下发现,先找上下,在对称走就行。
即,反复横跳,从1,1--n,m--1,2--n,m-1--......--1,m--n,1--2,1--.....
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int n, m;
vector<int>vec;
int main()
{
n = read(), m = read();
if (n & 1)
{
upd(i, 1, n / 2)
{
upd(j, 1, m)
{
printf("%d %d\n%d %d\n", i, j, n - i+1, m - j+1);
}
}
if(m%2)
{
upd(j, 1, m / 2)
{
printf("%d %d\n%d %d\n", n / 2 + 1, j, n / 2 + 1, m - j + 1);
}
printf("%d %d\n", n / 2 + 1, m / 2 + 1);
}
else {
upd(j, 1, m / 2)
{
printf("%d %d\n%d %d\n", n / 2 + 1, j, n / 2 + 1, m - j + 1);
}
}
}
else {
upd(i, 1, n / 2)
{
upd(j, 1, m)
{
printf("%d %d\n%d %d\n", i, j, n - i + 1, m - j + 1);
}
}
}
return 0;
}
橙橙橙