D - Circle Lattice Points (atcoder.jp)
题面 给出圆心和半径 求出在圆内的坐标为整数的点的个数
思路枚举 y 坐标 求对于每个 y ,x 坐标的左右端点。
但是有很毒瘤的精度问题,需要给半径加上一个很小的数。
C - Digital Graffiti (atcoder.jp)
有一个 H 行 W 列的表格,格子要么为黑色,用‘#’表示,要么为白色,用‘.’表示。第一行和最后一行,第一列和最后一列都是白色格子。 考虑黑色部分组成的多边形,问多边形有多少条边? 保证表格中,黑色部分为四联通区域,白色部分也为四联通区域。所谓四联通,即通过上、下、左、右四个方向,可以访问所有格子。 表格中至少存在一个黑色格子。
在一个小的正方形区域内(2 * 2),如果有1个 或者 3 个 ‘#’ 该区域内则存在一个拐点,多边形的边长数等于顶点数,所以遍历一遍即可。
E - Come Back Quickly (atcoder.jp)
因为是单向边,开始想每一条边只存在于一个单向环中,所以直接tarjan缩点,将边权加在一块就行了,最后输出所在联通块的权值,但是很显然是不正确的,因为同一条边可以在多个环中有贡献。
正解为 堆优化的dj ,对每个点跑一遍dj , 初始将 i 的邻接点加入即可,用dist[i] 记录最短距离,具体看代码
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
const int N = 1e5 + 10;
int n,m;
int e[N],ne[N],w[N],idx;
int h[N];
void add(int a,int b,int c){
e[++ idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx;
}
int dist[N];
int st[N];
typedef pair<int,int> PII;
void dj(int u)
{
memset(dist, 0x3f, sizeof dist);
memset(st , 0 , sizeof st);
priority_queue<PII ,vector<PII> , greater<PII>> q;
for(int i = h[u] ;i ;i = ne[i])
{
int j = e[i];
dist[j] = min(dist[j] , w[i]);
q.push({dist[j] , j});
}
while(q.size())
{
auto t = q.top();
q.pop();
if(st[t.second])continue;
st[t.second] = true;
for(int i = h[t.second];i ;i = ne[i])
{
int j = e[i];
if(dist[j] > dist[t.second] + w[i])
{
dist[j] = dist[t.second] + w[i];
}
q.push({dist[j] , j});
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= m;i ++){
int a,b,c;cin >> a >> b >> c;
add(a , b, c);
}
for(int i = 1;i <= n;i ++)
{
dj(i);
if(dist[i] != 0x3f3f3f3f){
cout << dist[i] << endl;
}
else cout << "-1" << endl;
}
return 0;
}