Panasonic Programming Contest (AtCoder Beginner Contest 186)

@[toc](Panasonic Programming Contest (AtCoder Beginner Contest 186))

导读:
简单的题目,只说明题意,或者直接说明结论
下面的难题,会做详细的解释和证明
立个flag,在座的大佬们做个见证:一个月刷60场ABC,现在2021/7/3,第十八天,已打卡十四场。

A - Brick

求下取整

void work()
{
  int a, b; cin >> a >> b;
  cout << a / b << endl;
}

B - Blocks on Grid

删去一些格子,让所有位置的高度相同

void work()
{
  int n, m; cin >> n >> m;
  int g[110][110] = {0};
  int h = 1e9;
  for (int i = 1; i <= n; i ++ )
    for (int j = 1; j <= m; j ++ )
    {
      cin >> g[i][j];
      h = min(h, g[i][j]);
    }
  int sum = 0;
  for (int i = 1; i <= n; i ++ )
    for (int j = 1; j <= m; j ++ )
      sum += g[i][j] - h;
  cout << sum << endl;
}

C - Unlucky 7

问从1到n,有多少个数,他的十进制和八进制的每一位都没有7的数字有多少个

void work()
{
  int n; cin >> n;
  int sum = 0;
  for (int i = 1; i <= n; i ++ )
  {
    //十进制
    int t = i;
    bool flag = true;
    while (t)
    {
      if (t % 10 == 7)
      {
        sum ++;
        flag = false;
        break;
      }
      t /= 10;
    }
    //八进制
    t = i;
    while (t && flag)
    {
      if (t % 8 == 7)
      {
        sum ++;
        break;
      }
      t /= 8;
    }
  }
  cout << n - sum << endl;
}

D - Sum of difference

首先,给数列按照从大到小排个序,将绝对值拿掉。然后,将式子展开,给每个位置补上一个|啊|aii - aii|,然后观察式子发现这就是一个前缀和处理的问题。

#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int n;
long long a[N], s[N];
int main()
{
  cin >> n;
  for (int i = 1; i <= n; i ++ )
    scanf("%lld", &a[i]);
  sort(a + 1, a + 1 + n);
  reverse(a + 1, a + 1 + n);
  for (int i = 1; i <= n; i ++ )
    s[i] = s[i - 1] + a[i];
  // for (int i = 1; i <= n; i ++ ) cout << a[i] << " "; cout << endl;
  // for (int i = 1; i <= n; i ++ ) cout << s[i] << " "; cout << endl;
  reverse(s + 1, s + 1 + n);
  long long sum = 0;
  reverse(a + 1, a + 1 + n);
  for (int i = 1; i <= n; i ++ )
  {
    sum += s[i] - (n - i + 1) * a[i];
  }
  cout << sum << endl;
  return 0;
}

E - Throne

题意:在一个圆上,王座在位置0,当前位置在S,我们每次走k步,问最少多少步可以到达0
也就是x*k % N = (N - s) % N

#include <bits/stdc++.h>
using namespace std;
long long exgcd(long long a, long long b, long long&x, long long& y)
{
  if (b == 0)
  {
    x = 1, y = 0;
    return a;
  }
  long long d = exgcd(b, a % b, y, x);
  y = y - a / b * x;
  return a;
}
void work()
{
  long long n, s, k; cin >> n >> s >> k;
  long long d = __gcd(n, __gcd(s, k));
  n /= d; s /= d; k /= d;
  long long x, y;
  if (__gcd(k, n) == 1)
  {
    long long ans = exgcd(k, n, x, y);
    x = (n + x % n) % n;
    ans = n - x * s % n;
    cout << ans << endl;
  }
  else
  {
    cout << "-1" << endl;
  }
}
int main()
{
  int T; cin >> T;
  while (T -- ) work();
  return 0;
}

F - Rook on Grid

从第一行开始枚举每一行,直到i=n,结束枚举
将每个点按照以行为第一关键字,列为第二关键字,按照从小到大的顺序排序,方便枚举
将第一行第一次出现g[1][j]=1的后面的所有格点都给标记g[1][j] = 1
将第一列第一次出现g[i][1]=1的后面的所有格点都给标记g[i][1] = 1
找到当前行的第一个g[i][j] = 1,s[m] - s[j - 1]就是当前行的个数,同时,标记当前行每个1
然后将每一行加在一起
这样,单点修改区间查询,可以使用树状数组

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200010;
#define lowbit(x) x & -x
int n, m, k;
ll tr[N];
bool st[N];
vector<int> g[N];
void add(int x, int c)
{
  for (; x <= m; x += lowbit(x) ) tr[x] += c;
}
ll query(int x)
{
  ll ans = 0;
  for (; x; x -= lowbit(x)) ans += tr[x];
  return ans;
}
int main()
{
  scanf("%d%d%d", &n, &m, &k);
  int x, y, minx = 1e9, miny = 1e9;
  for (int i = 0; i < k; i ++ )
  {
    scanf("%d%d", &x, &y);
    if (x == 1) miny = min(miny, y);
    if (y == 1) minx = min(minx, x);
    g[x].push_back(y);
  }
  if (miny < 1e9) for (int j = miny + 1; j <= m; j ++ ) g[1].push_back(j);
  if (minx < 1e9) for (int i = minx + 1; i <= n; i ++ ) g[i].push_back(1);
  for (int i = 1; i <= n; i ++ ) sort(g[i].begin(), g[i].end());
  ll ans = 0;
  for (int i = 1; i <= n; i ++ )
  {
    if (g[i].size() == 0) continue;
    for (int y : g[i]) if (!st[y]) st[y] = true, add(y, 1);
    ans += query(m) - query(g[i][0] - 1);
  }
  cout << 1ll * n * m - ans << endl;
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值