第一层有2个单元 其他每层有k个单元 (n-2)/k 即可得到答案**注意* * 向上取整
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int main()
{
int T;
cin>>T;
while(T--)
{
int n,k;
cin>>n>>k;
if(n==1) {cout<<1<<endl;continue;}
int res = (n-2)/k;
if((n-2)%k) res++;
cout<<++res<<endl;
}
}
B.Symmetric Matrix
条件:
①如果出现第二个位置和第三个位置相等的方块即可
②大正方体的边长不能是奇数
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int main()
{
int T;
cin>>T;
while(T--)
{
bool st=0,f=0;
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
int a,b,c,d;
cin>>a>>b>>c>>d;
// cout<<a<<b<<c<<d;
if(b==c)
{
st=1;
}
}
if(m%2)
{
puts("NO");
continue;
}
if(st) puts("YES");
else puts("NO");
}
}
C. Increase and Copy
题意:给一个正整数n,和一个数组{1},有两个操作①让数组中任意数+1②复制任意一个数组中的数到数组尾端 问最少多少次操作可以让数组中全部数字的和>=n
思路:贪心,肯定是先将某个数加到一定程度然后在去一直复制最快,那么设加到m然后辅助k次 可以退出我们要满足 m*k≥n 容易看得出我们枚举m和k的时候 在最小操作次数的前提下 是对立枚举的(当m增加的时候要满足k减小),所以一定有一个阈值 也就是 m = k =sqrt(n)的时候,那就可以求解了 由于求的是≥n 所以除法向上取整
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
int res = sqrt(n);
//cout<<res<<"---";
long long ans = res - 1;
if(n % res) ans++;
ans+=(n-res)/res;
cout<<ans<<endl;
}
}
D. Non-zero Segments
题意:给定一个序列,其中会出现子段加和为0的情况,此时你可以向序列中添加任意值,问最少添加多少次能使任意子段和!=0
思路:前缀和+哈希 当子段和=0的时候肯定有 sum[r] - sum[l-1]==0 也就是 sum[r] == sum[l-1] ,所以我们构建前缀和后 将每一段的前缀和插入map中,并记录他的位置,当遍历到该前缀和出现过并且上一次出现的位置是在已添加任意值的子段的右端点后的时候 答案++即可
#include<bits/stdc++.h>
using namespace std;
const int N = 200000 + 10;
typedef long long ll;
map<ll,ll> m;
ll ans;
ll aa,ss;
int main()
{
int n;
cin>>n;
int l=0;
m[0] = 1;
for(int i = 2;i<=n+1;i++)
{
cin>>aa;
ss += aa;
if(m[ss] && m[ss] >= l-1) ans++,l=i;
m[ss] = i;
}
cout<<ans;
}