[題解]AtCoder Beginner Contest 174
AtCoder Beginner Contest 174
閒來無事摸了一場ABC
A
按題意模擬即可 \(\leq 30\)輸出 Yes 否則 No
#include <bits/stdc++.h> using namespace std; #define ll long long #define lowbit(a) ((a) & -(a)) #define clean(a, b) memset(a, b, sizeof(a)) const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f; const int maxn = 2e6 + 9; int _; //======================================================================== //======================================================================== int main() { int n; scanf("%d",&n); if(n>=30) puts("Yes"); else puts("No"); return 0; }
B
給你一些座標 問有多少座標與原點距離小於\(d\)
怕有誤差可以把開根號換成\(d*d\) 記得開long long
(大於小於看反了 慢了幾分鐘)
#include <bits/stdc++.h> using namespace std; #define ll long long #define lowbit(a) ((a) & -(a)) #define clean(a, b) memset(a, b, sizeof(a)) const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f; const int maxn = 2e6 + 9; int _; //======================================================================== //======================================================================== int main() { ll n,d,x,y,cnt=0; scanf("%lld%lld",&n,&d); d=d*d; for(int i=1;i<=n;i++) { scanf("%lld%lld",&x,&y); if(d>=x*x+y*y) cnt++; } printf("%lld\n",cnt); return 0; }
C
有一個序列\(7,77,777,7777……\)
給你一個數k,問k的倍數是否有可能是上述序列中的元素
如果是,請輸出最小是幾個七
貌似可以暴力做,最大就是\(k\)個\(7\)了
首先只有尾數是\(1,3,7,9\)的數的倍數結尾有可能是\(7\)
其次 有\(1\leq i\leq k\),如果\(i\)個\(7\% k==0\)那麼輸出i就可以了,否則-1
要用到高精取模 學到了學到了
我的程式碼還要特判\(1\)和\(7\) 可能是寫法問題
#include <bits/stdc++.h> using namespace std; #define ll long long #define lowbit(a) ((a) & -(a)) #define clean(a, b) memset(a, b, sizeof(a)) const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f; const int maxn = 2e6 + 9; int _; //======================================================================== //======================================================================== int main() { int n,sum=7; scanf("%d",&n); if(n%2==0) { printf("-1\n"); return 0; } if(n==1||n==7) { printf("1\n"); return 0; } for(int i=1;i<=n;i++) { if(sum==0) { printf("%d\n",i); return 0; } sum=(sum*10+7)%n; } printf("-1\n"); return 0; }
D
只可以通過把w變成R或者把R變成W或者交換RW使得W左邊沒有R
那麼這三種情況肯定有一個最優的,取最小就可
(但事實上好像只判斷第三種就可以)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a) & -(a))
#define clean(a, b) memset(a, b, sizeof(a))
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 9;
int _;
//========================================================================
char s[maxn];
//========================================================================
int main()
{
int n;
scanf("%d",&n);
scanf("%s",s);
int num1=0,num2=0;
for(int i=0;i<n;i++)
{
if(s[i]=='W') num1++;
else num2++;
}
int cnt=0;
for(int i=0;i<n;i++)
{
if(i<num2)
{
if(s[i]!='R') cnt++;
}
else
{
if(s[i]!='W') cnt++;
}
}
printf("%d\n",min(num1,min(num2,cnt/2)));
return 0;
}
E
給你一些長度的木頭,只可以砍k次,使得砍完的木頭們的最高高度最矮,輸出最高高度
想挺久的不知道怎麼分配
後來突然想到 可以二分答案做,如果高度很小,那就是不成立的,如果高度很高,那一定成立,存在單調性,根據題意,求的就是滿足條件的最小值
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a) & -(a))
#define clean(a, b) memset(a, b, sizeof(a))
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e6 + 9;
int _;
//========================================================================
int a[maxn],n,k;
bool check(int now)
{
int sum=0;
for(int i=1;i<=n;i++)
{
sum+=(a[i]-1)/now;
}
if(sum<=k) return 1;
return 0;
}
int two_points(int minn,int maxx)
{
int l=minn,r=maxx,mid,ans;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid)) r=mid-1;
else l=mid+1;
ans=r+1;
}
return ans;
}
//========================================================================
int main()
{
int maxx=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
maxx=max(maxx,a[i]);
}
int ans=two_points(1,maxx);
printf("%d\n",ans);
return 0;
}
F
給你一個序列,每個數字代表一種顏色
有q組詢問 每組詢問問在[l,r]內有多少種不同的顏色
這題很眼熟欸,洛谷原題 HH的項鍊 樹狀陣列or線段樹
首先對於[l,r]每個顏色最有用的就是在這個區間內最靠右的位置,那麼每個顏色我們只保留最右邊的那個,然後再進行區間和的查詢
實現的方式也很簡單,我們先記下來對於當前位置,與他相同顏色的前一個位置是在哪裡,把他這個位置的值-1,把當前位置的值+1(對於與他相同顏色的前一個位置存在,那麼那個位置的數值一定加過了,如果不存在,就不加)
先對q組詢問離線處理,按r排序可以降低複雜度,每次對於x[i-1].r到x[i].r,更新這個區間內的顏色(把當前位置顏色相同是上一個位置的值-1,把當前位置的值+1)
更新過後取sum(r)-sum(l-1)即可
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a) & -(a))
#define clean(a, b) memset(a, b, sizeof(a))
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e6 + 9;
int _;
//========================================================================
int c[maxn],a[maxn],last[maxn],pre[maxn],n,ans[maxn];
struct node
{
int l,r,num;
}x[maxn];
int cmp(node a,node b)
{
if(a.r==b.r) return a.l<b.l;
return a.r<b.r;
}
void update(int x,ll y,int n)///One point update
{
for(int i=x; i<=n; i+=lowbit(i))
c[i] += y;
}
ll get_sum(int x)///Interval query
{
ll ans = 0;
for(int i=x; i; i-=lowbit(i))
ans += c[i];
return ans;
}
//========================================================================
int main()
{
int q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(last[a[i]])
{
pre[i]=last[a[i]];
last[a[i]]=i;
}
else
{
pre[i]=maxn+1;
last[a[i]]=i;
}
}
for(int i=1;i<=q;i++)
{
scanf("%d%d",&x[i].l,&x[i].r);
x[i].num=i;
}
sort(x+1,x+1+q,cmp);
int j=1;
for(int i=1;i<=q;i++)
{
for(;j<=x[i].r;j++)
{
update(pre[j],-1,n);
update(j,1,n);
}
ans[x[i].num]=get_sum(x[i].r)-get_sum(x[i].l-1);
}
for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
return 0;
}