A. Image Scaling
簽到題,找出舉行寬高以後直接除以它們的 \(\gcd\) 使它們互質即可。
(這道題居然會有人又 WA 又 RE,我不說是誰)
點選檢視程式碼
#include<cstdio>
#include<cstring>
using namespace std;
const int N=505;
int n,m,x1,y1,x2,y2;
char g[N][N];
int gcd(int x,int y){return y ? gcd(y,x%y) : x;}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%s",g[i]+1);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
if(g[i][j]=='x')
{
x1=i,y1=j;
break;
}
if(x1) break;
}
for(int i=n;i>=1;i--)
{
for(int j=m;j>=1;j--)
if(g[i][j]=='x')
{
x2=i,y2=j;
break;
}
if(x2) break;
}
int h=x2-x1+1,w=y2-y1+1;
int d=gcd(w,h);
w/=d,h/=d;
for(int i=1;i<=h;i++)
{
for(int j=1;j<=w;j++)
putchar('x');
putchar('\n');
}
return 0;
}
K. Kill The Monsters
貪心,每次一定優先對最大的那個進行操作二,而操作一的次數應當是剩下所有數的最大值。
所以模擬砍最大數的過程(可以用優先佇列找最大數),然後統計操作次數並對所有的 \((\max a + alr)\) 取最小值(其中 \(alr\) 表示已經進行過的操作次數)。
因為沒有判斷全部進行操作二的可能性而 WA 了好多發,最後應當用最終的 \(alr\) 再更新一邊答案。
每次操作都將其中一個除以 \(k\),所以時間複雜度為 \(O(N \log_K \max a_i )\)
還要注意特判 \(k=1\) 的情況,此時無法進行操作二,只需取最大值即可。
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N=1e5+5;
int n;
long long k,a[N];
priority_queue<long long> pq;
int main()
{
scanf("%d%lld",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
pq.push(a[i]);
}
if(k==1)
{
printf("%lld\n",pq.top());
return 0;
}
long long ans=1e18,alr=0;
while(!pq.empty())
{
long long x=pq.top(); pq.pop();
ans=min(ans,x+alr);
x/=k;
if(x>0) pq.push(x);
alr++;
}
printf("%lld\n",min(ans,alr));
return 0;
}