2022.4.2
AtCoder Beginner Contest 246
A - Four Points
统计一下谁只出现过一次输出就行,看别人直接异或更简洁
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e8;
int x[500], y[500];
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
for (int i = 1; i <= 3;i++)
{
int a, b;
cin >> a >> b;
x[150 + a]++;
y[150 + b]++;
}
for (int i = 0; i <= 300;i++)
{
if(x[i]==1)
cout << i - 150 << ' ';
}
for (int i = 1; i <= 300;i++)
{
if(y[i]==1)
cout << i-150 << ' ';
}
return 0;
}
B - Get Closer
sin和cos,相似一下
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e8;
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
double a, b;
double ans = 0;
cin >> a >> b;
double c = sqrt(1.0 * a * a + 1.0* b * b);
double bl = 1.0 / c;
printf("%.12lf %.12lf", a * bl, b * bl);
return 0;
}
C - Coupon
排序一下,从价格大的商品开始用优惠券,如果当前商品的价格能够用完所有优惠券那么就全部用完并退出,否则对于当前商品用超过它价格的优惠券。最后如果优惠券还有剩余则在排序一遍,将剩下的优惠券用完。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+10,INF=1e8;
ll a[N];
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
ll n, k, x;
cin >> n >> k >> x;
ll sum = 0;
for (int i = 1; i <= n;i++)
{
cin >> a[i];
}
sort(a + 1, a + 1 + n);
for (int i = n; i >= 1;i--)
{
if(k)
{
if(k*x<=a[i])
{
a[i] -= k * x;
k = 0;
break;
}
else
{
k -= a[i] / x;
a[i] %= x;
}
}
else
break;
}
if(k!=0)
{
sort(a + 1, a + 1 + n);
for (int i = n; i >= 1;i--)
{
if(k)
{
k --;
a[i] = 0;
}
else
break;
}
}
for (int i = 1; i <= n;i++)
sum += a[i];
cout << sum;
return 0;
}
D - 2-variable Function
二分,因为题目已说明n<=1e18,观察三次方程发现a和b最大只能为1e6,否则超过1e18。我们考虑二分,但这时候有两个变量a和b,考虑到a,b的范围不是很大,可以选择直接枚举a,然后二分mid(即b),求出f(i,mid),并与n比较,如果>=n就立马更新最小值(三次方程),不能放在最后才更新。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e8;
ll n, ans = 1e18 + 1;
ll f(ll a,ll b)
{
ll ans = a * a * a + a * a * b + a * b * b + b * b * b;
return ans;
}
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
cin>>n;
for (ll i = 0; i <= 1e6;i++)
{
ll l = 0, r = 1e6;
while(l<r)
{
ll mid = l + r >> 1;
ll res = f(i, mid);
if(res>=n)
{
ans = min(ans, res);
r = mid;
}
else l=mid+1;
}
}
cout << ans;
return 0;
}
E - Bishop 2
一开始觉得麻烦的是这个象可以斜着走,只要在同一个方向斜着走那么它可以只花一步走到同方向的任意位置,说是相当于一张边权为0和1的无向图,找到某点的最短路。用dijsktra应该也可以,就是1500*1500建图太麻烦了,题解用的是01—BFS,也就是双端队列bfs,之前蓝书有做过一道题,需要用到deque,因为队列的点需要满足两段性和单调性,当边权为0的时候,我们放入队头,边权为1时我们放入队尾,尽管一个点可能多次入队,但当这个点一次被取出时,所得的就是到这个点的最短路。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<deque>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1500+10,INF=1e9;
char mp[N][N];
int n,sx,sy,ex,ey,vis[N][N][4],dis[N][N][4];
int dx[] = {-1, -1, 1, 1}, dy[] = {-1, 1, -1, 1};
struct node
{
int x, y, dir;
};
bool check(int x,int y)
{
return x >= 1 && x <= n && y >= 1 && y <= n && mp[x][y] != '#';
}
int bfs()
{
deque<node> que;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= n;j++)
{
for (int k = 0; k < 4;k++)
dis[i][j][k] = INF;
}
}
for (int i = 0; i < 4;i++)
{
int x = sx + dx[i], y = sy + dy[i];
if(check(x,y))
{
que.push_back({x, y, i});//初始化四个方向
dis[x][y][i] = 1;//为1是因为第一次走到任何方向都需要耗费1步
}
}
while(que.size())
{
auto t = que.front();
que.pop_front();
int nowx = t.x, nowy = t.y, nowd = t.dir;
if(vis[nowx][nowy][nowd])
continue;
vis[nowx][nowy][nowd] = 1;
if(nowx==ex&&nowy==ey)//第一次取出时如果是终点就返回。
return dis[nowx][nowy][nowd];
for (int i = 0; i < 4;i++)
{
int nex = nowx + dx[i], ney = nowy + dy[i];
int w = 0;
if(i!=nowd)
w++;
if(check(nowx,nowy)&&(dis[nex][ney][i]>dis[nowx][nowy][nowd]+w))
{
dis[nex][ney][i] = dis[nowx][nowy][nowd]+w;
if(i==nowd)//同方向入对头
que.push_front({nex, ney, i});
else//不同入队尾
que.push_back({nex, ney, i});
}
}
}
return -1;
}
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n;
cin >> sx >> sy >> ex >> ey;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> mp[i][j];
}
}
cout << bfs();
return 0;
}