牛客周赛Round 83全解
这次是我的首次ak
比赛链接:https://ac.nowcoder.com/acm/contest/102896#description
A.和猫猫一起起舞!
思路:小小签到
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
//#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
const ll N = 205000;
#define F first
#define S second
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l, r;
bool operator<(const s& a)
{
return r < a.r;
}
};
int main()
{
fio();
int t;
//cin>>t;
t=1;
while(t--)
{
//int n;
char n;
cin>>n;
if(n=='U'||n=='D')cout<<"L"<<endl;
else cout<<"U"<<endl;
}
}
B.冒险猫猫参上!!
思路:1,2,1,2构造
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
//#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
const ll N = 205000;
#define F first
#define S second
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l, r;
bool operator<(const s& a)
{
return r < a.r;
}
};
int main()
{
fio();
int t;
cin>>t;
//t=1;
while(t--)
{
int n;
//char n;
cin>>n;
for(int i=1;i<=n;i++)
{
if(i&1)cout<<1<<" ";
else cout<<2<<" ";
}
cout<<endl;
}
}
C.泉神,启动!!!
思路:知道一个正整数x,要求y*x的数集是它的非空子集,我们直接想集合相等即可,因为我们总可以构造出如4545,366366这种循环类型的数字,只要y等于以10为底,x的长度为幂的数然后+1即为正确答案
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
//#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
const ll N = 205000;
#define F first
#define S second
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l, r;
bool operator<(const s& a)
{
return r < a.r;
}
};
int main()
{
fio();
int t;
cin>>t;
//t=1;
while(t--)
{
int n;
cin>>n;
//ll len=0;
ll ans=1;
while(n)
{
// len++;
ans*=10;
n/=10;
}
ans++;
cout<<ans<<endl;
}
}
D.大预言家!!!!
思路:通过观察发现边的规律为1 1 2 2 3 3 4 4...,还有偶数作为结尾且出现为第二次一定在左上角,奇数作为结尾且出现为第二次一定在右下角(此时设奇数为r,显然坐标为(r+1)/2,-(r+1)/2),通过二分我们可以找打符合答案的上一个结尾位置,然后倒推即可
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
//#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
const ll N = 205000;
#define F first
#define S second
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l, r;
bool operator<(const s& a)
{
return r < a.r;
}
};
int main()
{
fio();
int t;
cin>>t;
//t=1;
while(t--)
{
ll n;
cin>>n;
if(n==1)
{
cout<<0<<" "<<0<<endl;
continue;
}
n--;
ll l=1,r=1e9;
while(l<r)
{
ll mid=(l+r)/2;
if((1+mid)*mid>=n)r=mid;
else l=mid+1;
}
if((r+1)*r==n)
{
if(r&1)//右下角
{
cout<<(1+r)/2<<" "<<-(1+r)/2<<endl;
}
else
{
cout<<(r)/2-(r)<<" "<<-r/2+r<<endl;
}
}
else//大于t
{
if(r&1)
{
ll cz=(r+1)*r-n;
if(cz<=r)
{
cout<<(1+r)/2<<" "<<-(1+r)/2+cz<<endl;
}
else
{
cz-=r;
cout<<(1+r)/2-cz<<" "<<-(1+r)/2+r<<endl;
}
}
else
{
ll cz=(r+1)*r-n;
if(cz<=r)
{
cout<<(r)/2-(r)<<" "<<-r/2+r-cz<<endl;
}
else
{
cz-=r;
cout<<(r)/2-(r)+cz<<" "<<-r/2+r-r<<endl;
}
}
}
}
}
E.全都要!!!!!
思路:经典dp问题,显然我们可以根据实际状况对于每个位置投了几次骰子和骰子大小分别进行遍历,然后逐步优化出最大值,根据当前状态由前面推过来,记得一开始数组全初始化为大负数。最后取投了k次骰子的所有可能位置的价值最大即可。dp[i][z]即为在i位置投了第z次骰子的价值
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
//#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
const ll N = 205000;
#define F first
#define S second
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll l, r;
bool operator<(const s& a)
{
return r < a.r;
}
};
ll dp[10002][1002];
int main()
{
fio();
int t;
//cin>>t;
t=1;
while(t--)
{
int n,k;
cin>>n>>k;
vector<ll>a(n+5);
ll ans=-1e18;
for(int i=1;i<=n;i++)cin>>a[i];//每次移动1-6
for(int i=0;i<=n;i++)
{
for(int j=0;j<=k;j++)dp[i][j]=-1e18;
}
dp[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int z=max(i/6+(i%6>0),1);z<=min(k,i);z++)
{
for(ll j=1;j<=6;j++)
{
if(i-j<0)continue;
dp[i][z]=max(dp[i-j][z-1]+a[i],dp[i][z]);
if(z==k)
{
ans=max(ans,dp[i][z]);
}
}
}
}
cout<<ans<<endl;
}
}
F.水题!!!!!!
思路:bfs+优先队列或者说是最短路变形吧,把水流分3种情况即可,所以开了三维得vis数组作为标记,水源和下降的水视为同情况最好,我这里视作了不同情况,然后就比较暴力的写即可,主要是把一个障碍物摧毁了,得考虑下左右得水流流向(可以不要考虑),然后每次水流往左或者右边流时障碍物有没被摧毁(可以不要考虑),最后开个二维数组记录个时间戳的最小值即可.写的比较屎山一点
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
//#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
const ll N = 205000;
#define F first
#define S second
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll tm, l, r;
ll o;
friend bool operator<(const s& a, const s& b)
{
return a.tm > b.tm;
}
};
bool vis[1003][1003][4];
ll ti[1003][1003];
int main()
{
fio();
int n, m, h;
cin >> n >> m >> h;
string e[1004];
for (ll i = 1; i <= n; i++)
{
cin >> e[i];
e[i] = '0' + e[i];
for (ll j = 1; j <= m; j++)ti[i][j] = 1e18;
}
function<void(int, int)>bfs = [&](int x, int y)
{
priority_queue<s>f;
f.push({ 0,x,y,0 });
while (!f.empty())
{
ll tm = f.top().tm;
ll x = f.top().l;
ll y = f.top().r;
ll z = f.top().o;
f.pop();
if (vis[x][y][z])continue;//*=0,s=1,l=2,r=3
vis[x][y][z] = 1;
ti[x][y] = min(ti[x][y], tm);
if (z == 0)
{
if (x + 1 <= n)
{
if (e[x + 1][y] != '#')
{
f.push({ tm + 1,x + 1,y,1 });
}
else
{
f.push({ tm + h + 1,x + 1,y,1 });
if (y - 1 >= 1 && e[x][y - 1] != '#')f.push({ tm + 1,x,y - 1,2 });
if (y + 1 <= m && e[x][y + 1] != '#')f.push({ tm + 1,x,y + 1,3 });
}
}
}
else if (z == 1)
{
if (x + 1 <= n)
{
if (e[x + 1][y] != '#')
{
f.push({ tm + 1,x + 1,y,1 });
}
else
{
if (y - 1 >= 1 && (vis[x][y - 1][1] || e[x][y - 1] == '.' || e[x][y - 1] == '%'))f.push({ tm + 1,x,y - 1,2 });
if (y + 1 <= m && (vis[x][y + 1][1] || e[x][y + 1] == '.' || e[x][y + 1] == '%'))f.push({ tm + 1,x,y + 1,3 });
f.push({ tm + h + 1,x + 1,y,1 });
if (y - 1 >= 1 && vis[x + 1][y - 1][3])f.push({ tm + h + 1,x + 1,y,3 });
if (y + 1 <= m && vis[x + 1][y + 1][2])f.push({ tm + 1 + h,x + 1,y,2 });
}
}
}
else if (z == 2)
{
if (x + 1 <= n)
{
if (e[x + 1][y] != '#')f.push({ tm + 1,x + 1,y,1 });
else if (y - 1 >= 1)
{
if (e[x][y - 1] == '.' || vis[x][y - 1][1] || e[x][y - 1] == '%')f.push({ tm + 1,x,y - 1,2 });
}
}
else if (y - 1 >= 1)
{
if (e[x][y - 1] == '.' || vis[x][y - 1][1] || e[x][y - 1] == '%')f.push({ tm + 1,x,y - 1,2 });
}
}
else if (z == 3)
{
if (x + 1 <= n)
{
if (e[x + 1][y] != '#')f.push({ tm + 1,x + 1,y,1 });
else if (y + 1 <= m)
{
if (e[x][y + 1] == '.' || vis[x][y + 1][1] || e[x][y + 1] == '%')f.push({ tm + 1,x,y + 1,3 });
}
}
else if (y + 1 <= m)
{
if (e[x][y + 1] == '.' || vis[x][y + 1][1] || e[x][y + 1] == '%')f.push({ tm + 1,x,y + 1,3 });
}
}
}
};
for (ll i = 1; i <= n; i++)
{
for (ll j = 1; j <= m; j++)
{
if (e[i][j] == '*')
bfs(i, j);
}
}
for (ll i = 1; i <= n; i++)
{
for (ll j = 1; j <= m; j++)
{
if (e[i][j] == '%')
{
if(ti[i][j]==1e18)cout<<-1<<endl;
else
cout << ti[i][j] << endl;
}
}
}
}

浙公网安备 33010602011771号