打到了 R a n k 33 Rank\ 33 Rank 33,还是不错的。
第一次顺顺畅畅没有WA地AK了一场ABC,写篇题解纪念一下……
直接模拟即可。
分别枚举每个点并用已给的公式算出其与原点的距离,然后统计距离不大于 k k k的点数即可。
建议用 l o n g d o u b l e long\ double long double存储。
暴力即可,考虑如何快速判断 k k k个 1 1 1时其是否能被 n n n整除。
我们可以维护一个值,即当前这么多 1 1 1组成的数模 n n n的值。考虑在末尾加上一个 1 1 1后,原数 x x x变为了 10 x + 1 10x+1 10x+1,那么模数也乘 10 10 10加 1 1 1,即模数可以 O ( 1 ) O(1) O(1)维护。
当模数为 0 0 0时显然满足要求,立即输出并结束即可。注意当位数达到一定量的时候,应跳出循环输出 − 1 -1 −1。
显然,满足要求的条件是,左边清一色的 R R R且右边清一色的 W W W。
于是,我们算出 W W W的数量为 c n t cnt cnt,在原字符串的最后 c n t cnt cnt位中数出不为 W W W的字符数量,即为答案。
注意,这种做法的正确性在于,在后面 c n t cnt cnt位中,每遇到一个不是 W W W的字符就应当与前面 n − c n t n-cnt n−cnt个字符中一个不为 R R R的字符交换,此时满足要求且决策最优。
首先,思考这样一个问题: 如果一个块的长度为 x x x,每次把它劈成两个块,最终要求任何一个块的长度均不超过 l e n len len,求最少劈的次数。
我们可以贪心地操作,即对于长木块,每次都劈掉一块长度为 l e n len len的,直到满足要求,此时决策最优且劈的次数为 ⌈ a b ⌉ − 1 \lceil \frac a b \rceil -1 ⌈ba⌉−1。
回到原题,可以发现是一道有单调性的二分题(最小值最大, 最大值最小这种字眼应该很敏感吧)。我们每次判断: 能否让块的最大值最终不大于 m i d mid mid且劈的次数不多于 k k k次。判断的方式就是判断 ∑ i = 1 n ( ⌈ a i m i d ⌉ − 1 ) \sum_{i=1}^n (\lceil \frac {a_i} {mid} \rceil -1) ∑i=1n(⌈midai⌉−1)的值是否超过了 k k k,其中前者表示,分别考虑每个块至少要被劈的次数使得其产生的新块中不含大于 m i d mid mid的块。
时间复杂度为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)。
与 P 1972 P1972 P1972撞题,思路详见 P 1972 P1972 P1972。
看这里
#include
#define int long long
using namespace std;
int n;
signed main()
{
cin>>n;
if (n>=30) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}
#include
#define int long long
#define double long double
using namespace std;
int n,d,ans=0;
double x,y;
signed main()
{
cin>>n>>d;
for (int i=1;i<=n;i++)
{
cin>>x>>y;
double len=sqrt(x*x+y*y);
if (len<=d) ans++;
}
cout<<ans<<endl;
return 0;
}
#include
#define int long long
using namespace std;
int n,ii=0,now=0;
signed main()
{
cin>>n;
while (ii<=80000000)
{
ii++;
now=(now*10+7)%n;
if (now==0) return cout<<ii<<endl,0;
}
cout<<-1<<endl;
return 0;
}
#include
#define int long long
using namespace std;
int n,cnt=0,ans=0;
char a[200005];
signed main()
{
cin>>n;
for (int i=1;i<=n;i++) cin>>a[i];
for (int i=1;i<=n;i++)
{
if (a[i]=='W') cnt++;
}
for (int i=n-cnt+1;i<=n;i++)
{
if (a[i]!='W') ans++;
}
cout<<ans<<endl;
return 0;
}
#include
#define int long long
using namespace std;
int n,k,ans=1e9+7;
int a[200005];
inline int up(int aa,int bb)
{
if (aa%bb==0) return aa/bb;
else return (aa/bb)+1;
}
bool check(int len)//check函数
{
int tot=0;
for (int i=1;i<=n;i++) tot=tot+up(a[i],len)-1;
if (tot<=k) return true;
else return false;
}
int Binary_search(int l,int r)//递归式二分写法
{
if (l==r||l+1==r)
{
if (check(l)) ans=min(ans,l);
if (check(r)) ans=min(ans,r);
return ans;
}
int mid=(l+r)>>1;
if (check(mid))
{
ans=min(ans,mid);
return Binary_search(l,mid);
}
else return Binary_search(mid+1,r);
}
signed main()
{
cin>>n>>k;
for (int i=1;i<=n;i++) cin>>a[i];
cout<<Binary_search(1,1e9)<<endl;
return 0;
}
详见原题的题解。