【校内训练2019-11-13】种田

时间:2019-11-13
本文章向大家介绍【校内训练2019-11-13】种田,主要包括【校内训练2019-11-13】种田使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

【题目概括】

现在给定一个\(N\times M\)的矩形,每一个小矩形的长宽都是\(L\)

统计有多少种放置小矩形的方案,可以让矩形两两间距或者矩形到边缘的距离是定值。

【思路要点】

  • 第一种解法:
  • 我们设放置了\(n\)行的小矩形和\(m\)列的小矩形。
  • 那么行的间距就是\(x0=\frac{N-n\times L}{n+1}\),列的间距就是\(x1=\frac{M-m\times L}{m+1}\)
  • 根据题意可以联立得到方程:\((N+L)\times m-(M+L)\times n=M-N\)
  • 我们就通过\(exgcd\)就可以求解。
  • 第二种解法:
  • 我们在原来的大矩形后都加上一列一行\(L\)
  • 这样满足条件的小矩形可以放在每一个长宽为\(gcd(N+L,M+L)\)的矩形的任意一个位置。
  • 那么答案就是\(gcd(N+L,M+L)\)
  • 但是有一部分重复的答案。
  • 就是当\(N+L|M+L\)时(设\(N<M\)
  • 在最右下角会有一部分的重复,也就是白加了一列和一行,需要减掉。

【代码】

//program by author at the test
#include <bits/stdc++.h>

#define int long long 

using namespace std;

int exgcd(int a,int b,int&x,int&y){
  if(!b){
    x=1,y=0;
    return a;
  }
  int g=exgcd(b,a%b,y,x);
  y-=a/b*x;
  return g;
}

int n,m,l,ans;

void getrange(int&l,int&r,int x,int d,int n){
  l=(1-x)/d;
  while(l*d<1-x)
    ++l;
  while((l-1)*d>=1-x)
    --l;
  r=(n-x)/d;
  while(r*d>n-x)
    --r;
  while((r+1)*d<=n-x)
    ++r;
}

void aaa(){
  if(n==m){
    cout<<n/l<<'\n';
    return;
  }
  int A=l+n,B=l+m,f=m-n;
  int x,y;
  int g=exgcd(A,B,x,y);
  if(f%g){
    cout<<0<<'\n';
    return;
  }
  y=-y*f/g,x=x*f/g;
  int l1,l2,r1,r2;
  getrange(l1,r1,x,B/g,m/l);
    getrange(l2,r2,y,A/g,n/l);
  cout<<max(0ll,min(r1,r2)-max(l1,l2)+1)<<'\n';
}

signed main(){
//  freopen("field.in","r",stdin);
//  freopen("field.out","w",stdout);
  cin>>n>>m>>l;
  aaa();
  return 0;
}
#include <bits/stdc++.h>

#define FI first
#define SE second
#define REP(i, s, t) for (int i = s; i <= t; i++)
#define PER(i, s, t) for (int i = s; i >= t; i--)
#define pb push_back
#define mp make_pair

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef long double ld;

template <class T> void chkmax(T& x, T y) { x = max(x, y); }
template <class T> void chkmin(T& x, T y) { x = min(x, y); }

namespace input {
  template <class T>
  void read(T& x) {
    x = 0; char ch = 0; int f = 1;
    for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
    for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    x *= f;
  }
  void re(int& x) { read(x); }
  void re(ll& x) { read(x); }
  void re(ull& x) { read(x); }
  void re(char& x) { x = getchar(); }
  void re(string& x) { cin >> x; }

  template <class T, class... R>
  void re(T& x, R&... y) {
    re(x), re(y...);
  }
}
using namespace input;

namespace output {
  template <class T>
  void write(T x) {
    if (!x) { putchar('0'); return; }
    if (x < 0) putchar('-'), x = -x;
    static int top, stk[25]; top = 0;
    while (x) stk[++top] = x % 10, x /= 10;
    while (top) putchar(stk[top--] + 48);
  }
  void pr(int x) { write(x); }
  void pr(ll x) { write(x); }
  void pr(ull x) { write(x); }
  void pr(char x) { putchar(x); }
  void pr(string x) { cout << x; }
  void pp() { putchar(' '); }
  void ps() { puts(""); }

  template <class T, class... R>
  void pr(T x, R... y) {
    pr(x), pr(y...);
  }
}
using namespace output;

ll a, b, l;

ll gcd(ll a, ll b) {
  return !b ? a : gcd(b, a % b);
}

int main() {
  re(a, b, l);
  if (b > a)
    swap(a, b);
  pr(gcd(a + l, b + l) / l - ((a + l) % (b + l) == 0), '\n');
  return 0; 
}

原文地址:https://www.cnblogs.com/chhokmah/p/11848372.html