列表

详情


NC237405. Spiral

描述

You like to wander about, but you hate to reach any position more than once. Therefore, you develop a routine to follow to prevent that.

You will walk along a -sided spiral. Starting from , he will walk straightly to , and then turn left for , and then walk ahead  more unit, and then again turn left for . After passing  straight lines, you will repeat the process above but walk for  units for each line. After passing  lines, you will walk for  units for each line and so on.
Now given how many units you pass, you need to find out where you are. The figure below shows a -sided spiral.

输入描述

The first line contains an integer  (, the number of queries.

Then  lines follow, each line contains two integers  , denoting you walks for  units on -sided spiral.

输出描述

Find your final position  for each query. For convenience, You only need to output  for each query. Your answer will be considered correct if the absolute or relative error doesn't exceed .

示例1

输入:

3
10 3
10 4
10 5

输出:

1.633974596216
2.000000000000
-1.902113032590

说明:

In these three examples, your final positions are  and  respectively.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 368ms, 内存消耗: 2960K, 提交时间: 2022-10-14 17:16:26

#include <bits/stdc++.h>
using namespace std;
typedef long double db;
typedef long long ll;
const db pi=acosl(-1.0);
struct vir {
	db r, i;
	inline vir(db r_=0, db i_=0):r(r_), i(i_) {}
	inline vir& operator += (const vir &rhs) { r+=rhs.r; i+=rhs.i; return *this; }
	inline vir& operator -= (const vir &rhs) { r-=rhs.r; i-=rhs.i; return *this; }
	inline vir& operator *= (const vir &rhs) {
		db rr=r*rhs.r-i*rhs.i;
		db ii=r*rhs.i+i*rhs.r;
		r=rr; i=ii;
		return *this;
	}
	inline vir operator + (const vir &rhs) const { vir lhs=*this; return lhs+=rhs; }
	inline vir operator - (const vir &rhs) const { vir lhs=*this; return lhs-=rhs; }
	inline vir operator * (const vir &rhs) const { vir lhs=*this; return lhs*=rhs; }
	
	inline vir operator ! () const { return vir(r, -i); }
	inline db norm() const { return r*r+i*i; }
	inline vir operator / (const vir &rhs) const {
		vir res=(*this)*(!rhs);
		db len=rhs.norm();
		return vir(res.r/len, res.i/len);
	}
};
ll n, k;
inline ll get_t(ll lim) {
	ll l=0, r=n, mid, res=0;
	while(l<=r) {
		mid=(l+r)/2;
		if((__int128_t)mid*(mid+1)/2<=lim) {
			res=mid;
			l=mid+1;
		}
		else {
			r=mid-1;
		}
	}
	return res;
}
inline vir w(ll n) {
	n%=k;
	db a=2*pi*n/k;
	return vir(cosl(a), sinl(a));
}
inline db ans() {
	cin>>n>>k;
	int r=k/2;
	ll t=get_t(n/r);
	vir res=(vir(1, 0)-w(t*r))/(vir(1, 0)-w(r))-vir(t, 0)*w(t*r);
	res=res/(vir(1, 0)-w(1));
	n-=t*(t+1)/2*r;
	
	res+=vir(t+1, 0)*(w(t*r)-w(n/(t+1)+t*r))/(vir(1, 0)-w(1));

	ll id=n/(t+1)+t*r;
	n%=t+1;
	res+=vir(n, 0)*w(id);
	
	return res.r+res.i;
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cout<<fixed<<setprecision(12);
	int t; cin>>t;
	while(t--)
		cout<<ans()<<"\n";
	cout.flush();
	return 0;
}

C++ 解法, 执行用时: 495ms, 内存消耗: 3832K, 提交时间: 2022-07-03 14:39:57

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;

const ld PI = acos(-1);
using c = complex<ld>;

c power(c a, ll b, c res = 1) {
  for (; b; b /= 2, (a *= a))
    if (b & 1) (res *= a);
  return res;
}

int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  cout << fixed << setprecision(20);
  int T;
  cin >> T;
  while (T--) {
    ll n, k, d;
    cin >> n >> k, d = k / 2;
    auto w = c(cos(2 * PI / k), sin(2 * PI / k));
    auto s = [&] {
      ll l = 0, r = n;
      while (l < r) {
        ll mid = (l + r + 1) / 2;
        if (__int128(mid + 1) * mid / 2 <= n / d) {
          l = mid;
        } else {
          r = mid - 1;
        }
      }
      return r;
    }();
    auto A = (power(w, s * d) - c(1)) / (power(w, d) - c(1)) - c(s) * power(w, s * d);
    A /= (c(1) - w);
    n -= d * (s + 1) * s / 2;
    ll t = n / (s + 1), remain = n % (s + 1);
    auto B = c(s + 1) * power(w, s * d) * ((power(w, t) - c(1)) / (w - c(1)));
    auto C = c(remain) * power(w, s * d + t);
    auto res = A + B + C;
    // cout << res.real() << " " << res.imag() << "\n";
    cout << res.real() + res.imag() << "\n";
  }
}

上一题