赛时解决题目:A,B,L
L:
题意:
说给个9*9数独的数独表,然后让你改其中任意个数字变成'*'作为雷,不能全改,然后输出。
解题思路:
观察一下会发现,数字8最特殊,中间的格子旁边一定有八个格子,那么对于数独来说,肯定有数字8在数独表非边缘位置,那么只需要找到这个坐标即可。
///秋雨
char a[20][20];
void cout_ans()
{
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
cout<<a[i][j];
}cout<<'\n';
}
}
void solve()
{
bool ret=0;
ll x,y;
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
cin>>a[i][j];
if(a[i][j]=='9')a[i][j]='*';
if(a[i][j]=='8'&&i!=1&&i!=9&&j!=1&&j!=9)
{
ret=1;
x=i,y=j;
}
}
}
if(ret)
{
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
a[i][j]='*';
}
}
a[x][y]='8';
}
cout_ans();
}
B:
题意:
说给你n个数,你有一辆车距离某面墙d,问每次用这些数之一逼近,如果选取的数字大于d,那么距离变成h-d,h是对应的数字。问距离墙面最小距离是多少。
解题思路:
其实跟组合差不多,你会发现,这n的数字的gcd就是它每次能前进的最小步长,而因为它是gcd,所以又可以代替这些数字的作用,那么答案便很显然了,要么是d%gcd求出来的东西,要么是撞一下墙后得到的数值,我这里gcd出来的值用x代替,也就是x-d%x。两者取最小值即可。赛时我是后面稍微模拟了一下,不过完全没有必要。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define N (int)1e5+10
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
if(b) while((a%=b)&&(b%=a));
return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
b>>=1;
a=a*a%p;
}
return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀
///秋雨
ll a[N];
void solve()
{
ll n,d;cin>>n>>d;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=2;i<=n;i++)
{
a[i]=gcd(a[i],a[i-1]);
}
d%=a[n];
ll ans=d;
unordered_set<ll>st;
while(!st.count(d))
{
st.insert(d);
d-=a[n];
d=abs(d);
ans=min(ans,d);
}
cout<<ans<<'\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
// cin>>t;
while(t--)
{
solve();
}
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,
///而后,春天再度归来。
A:(组合)
题意:
这题对于我来说,难,但想出来好像又很简单。
题意是:有n个人,每个人都有自己对应的体力 h[i],然后在河的一岸,有艘破船,这些人想过岸,但是每次坐船的时候都会消耗1点体力(不管是过去或回来),并且这艘船,至少得有L个人才能开动,最多能载R个人,问能不能全部过去。
解题思路:
一开始,我往模拟上面想,想的老对老对了,然后一交,欸嘿,wa了,wa了三发后老实了,开始想别的,然后就想到了船夫的问题(还是船夫的问题)。
我们可以贪心的知道,我们肯定希望,运过去的人越多越好,也就是最好满满当当坐R个人然后塞R-L个人过去,所以我们可以知道我们最大的渡河次数(只过去,不算回来的)是yun=(n-r+(r-l-1))/(r-l);这应该很容易理解。
然后因为每一次运都需要船夫,所以每一次运我们需要找到l个壮丁来当船夫(就因为这个一开始干模拟去了,过不去老不开心了),那么我们就给这n个人按照体力值排个序,我们处理一下h[i],让h[i]=h[i]-1>>1;为什么呢,h[i]-1说明它可以把自己运过去,h[i]-1>>1说明它可以承担船夫做一次来回的次数。
我们设一个变量ans作为需要船夫的个数。一开始为0。
那么我们从大到小遍历,对于前L个人,如果体力值超过了yun,也就是说,每一次船往来他都能干苦力,那么便不用对ans做处理,但也不能加上h[i],因为一个人只能在一次往返中担任一个船夫的任务,如果小于yun,那么这个船夫只能填上h[i]次的往返,所以ans需要+h[i]-yun,也就是说,我们需要补上yun-h[i]个船夫空位的意思。
对于后续的人,如果还存在大于yun的体力的人,那肯定意味着,我们必然拥有L个人能跑完所有yun次往返,如果不存在,那么我们可以给他分配它他当船夫的位置,因为遍历到这,又不符合大于yun,所以这个船夫肯定最多担任小于yun次的 往返,不用考虑说他一个人干两个人活的问题。所以这里直接加上h[i]即可。
那么最后再判断一下,ans是否大于等于0(是否可用船夫数量大于需要的数量),输出yes/no即可。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define N (int)5e5+10
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
if(b) while((a%=b)&&(b%=a));
return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
b>>=1;
a=a*a%p;
}
return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀
///秋雨
ll h[N];
void solve()
{
ll n,l,r;
cin>>n>>l>>r;
// priority_queue<ll,vector<ll>,greater<ll>>q;
ll ans=0;
for(int i=1;i<=n;i++)
{
cin>>h[i];h[i]=(h[i]-1)>>1;///运的次数
}
ll yun=(n-r+(r-l-1))/(r-l);
sort(h+1,h+1+n);
reverse(h+1,h+1+n);
for(int i=1;i<=n;i++)
{
if(i<=l&&h[i]<=yun)ans-=yun-h[i];
else if(i>l)ans+=h[i];
}
// cout<<ans<<'\n';
if(ans>=0) cout<<"Yes\n";
else cout<<"No\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
// cin>>t;
while(t--)
{
solve();
}
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,
///而后,春天再度归来。