这场比较简单
小红的矩阵构造
思路
- 如果
为奇数,那么直接按从上到下,从左往右的顺序,打印
到
。
- 如果
为偶数,也是按类似的顺序,不同的是,在偶数层要翻转一下打印顺序。
代码实现
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int p = 1;
for(int i=1;i<=n;i++){
vector<int>tmp;
for(int j=1;j<=n;j++){
tmp.push_back(p++);
}
if(n%2==0 && i%2==0){
reverse(tmp.begin(),tmp.end());
}
for(int x:tmp) cout<<x<<' ';
cout<<'\n';
}
}
小红的因子
思路
直接试除法找符合条件的因子即可,然后在其中取最小值即为答案。
代码实现
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int T;
cin>>T;
while(T--){
int n;
cin>>n;
int ans = n;
for(int i=1;i<=n/i;i++){
if(n%i==0){
int m1 = n,m2 = n/i;
if(m1*m1>n) ans = min(ans,m1);
if(m2*m2>n) ans = min(ans,m2);
}
}
cout<<ans<<'\n';
}
}
小红的小数点串
思路
贪心的想,要使分割后的每一个数尽可能大,那么就要使得数字尽可能不在小数位上,同时保证分割是合法的,所以把每个小数点后一位数字为分割点。
代码实现
#include <bits/stdc++.h>
using namespace std;
int n;
double ans;
string s,t;
int main()
{
cin>>s;
n = s.size();
for(int i=0;i<n;i++){
int j=i;
while(j<n && s[j]!='.'){
t += s[j++];
}
if(s[j]=='.'){
t += s[j++];
t += s[j++];
// stof 字符串转浮点数函数
ans += stof(t);
i = j-1;
}else{
// stol 字符串转长整数函数
ans += stol(t);
i = j-1;
}
t.clear();
}
printf("%.1lf",ans);
}
小红的数组操作
思路
- 数组的最大值越小,需要的操作次数越多,显然是有二段性的,可以直接二分数组的最大值。
- 当前数组的最大值为
,那么需要的最小操作次数为
,只需要判断
与
的大小关系即可知道是否可以使得数字的最大值达到
。
代码实现
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
#define int long long
int n,k,x;
__int128 a[N];
// 注意数据范围比较大要开 __int128
int check(__int128 ma)
{
__int128 sum = 0;
for(int i=1;i<=n;i++){
if(a[i]>ma){
__int128 d = a[i]-ma;
sum += (d+x-1)/x;
}
}
return sum<=k;
}
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int read()
{
int x=0,f=1;
char ch=nc();
while(ch<48||ch>57)
{
if(ch=='-')
f=-1;
ch=nc();
}
while(ch>=48&&ch<=57)
x=x*10+ch-48,ch=nc();
return x*f;
}
void write(__int128 x)
{
if(x<0)
putchar('-'),x=-x;
if(x>9)
write(x/10);
putchar(x%10+'0');
return;
}
signed main()
{
n = read(),k = read(),x = read();
for(int i=1;i<=n;i++){
a[i] = read();
}
__int128 l = -1e18,r = 1e9;
while(l<r){
__int128 mid = (l+r-1)/2;
// (l+r)/2 是在非负数运算下是下取整,实际上是向零取整
// 当二分涉及到负数的时候需要改成 (l+r-1)/2
if(check(mid)) r=mid;
else l=mid+1;
}
write(r);
}