链接:https://ac.nowcoder.com/acm/problem/208246
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
每逢佳节胖三斤,牛牛在过去的节日里长胖了,连拐弯都困难,甚至会卡在门上,所以他很讨厌拐弯。给你一个N*N(2≤N≤100)的方格中,‘x’表示障碍,‘.’表示没有障碍(可以走),牛牛可以从一个格子走到他相邻的四个格子,但是不能走出这些格子。问牛牛从A点到B点最少需要转90度的弯几次。
输入描述:
第一行一个整数:N,下面N 行,每行N 个字符,只出现字符:‘.’,‘x’,‘A’,‘B’;表示上面所说的矩阵格子,每个字符后有一个空格。
输出描述:
一个整数:最少转弯次数。如果不能到达,输出-1。
示例1
输入
复制
3
. x A
. . .
B x .
输出
复制
2
备注:
开始和结束时的方向任意。
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <cstring>
#include <vector>
#include<cstdio>
using namespace std;
char mp[110][110];
int vis[110][110];
int res=0x3f3f3f3f;
int sx,sy,zx,zy;
int dx[]={1,-1,0,0};
int dy[]={0,0,-1,1};
int n;
void dfs(int x,int y,int sum,int st){
if(mp[x][y]=='B'){
res=min(res,sum);
return ;
}
if(sum>=res)return ;
for(int i=0;i<4;i++){
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=0&&xx<n&&yy>=0&&yy<n&&!vis[xx][yy]&&mp[xx][yy]!='x'){
if(st==-1){
vis[xx][yy]=1;
dfs(xx,yy,sum,i);
vis[xx][yy]=0;
}
else if(st!=i){
vis[xx][yy]=1;
dfs(xx,yy,sum+1,i);
vis[xx][yy]=0;
}
else {
vis[xx][yy]=1;
dfs(xx,yy,sum,i);
vis[xx][yy]=0;
}
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>mp[i][j];
}
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(mp[i][j]=='A'){
vis[i][j]=1;
dfs(i,j,0,-1);
}
if(res==0x3f3f3f3f)cout<<-1<<endl;
else
cout<<res<<endl;
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/6164/B
来源:牛客网
题目描述
牛牛是怎么胖的呢?当然是因为他太热爱吃零食了,牛牛给他的每一份零食编了号,每次他会拿出编号在[a,b]区间里能被8整除却不能被另外一些数中的任意一个整除的零食吃掉。现在请你帮他算一算他这一次到底能吃多少份零食吧?
输入描述:
第一行一个数n,代表不能被整除的数的个数。
第二行n个数,中间用空格隔开。
第三行两个数a,b,中间一个空格。
输出描述:
一个整数,为牛牛能吃到的零食份数,也就是[a,b]间中能被8整除却不能被给出的那n个数中任意一个整除的数的个数。
示例1
输入
复制
3
7764 6082 462
2166 53442
输出
复制
6378
说明
1≤n≤15,1≤a≤b≤10^9
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
ll ans, s[25], a, b;
int n;
ll lcm(ll x, ll y)
{
return x * y / __gcd(x, y);
}
void dfs(ll x, ll y, ll t)
{
if (y > b)
return;
if (x & 1)
ans += b / t - a / t;
else
ans -= b / t - a / t;
for (int i = y + 1; i <= n; i++)
{
dfs(x + 1, i, lcm(t, s[i]));
}
return;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%lld", &s[i]);
}
scanf("%lld%lld", &a, &b);
a--;
dfs(1, 0, 8);
printf("%lld", ans);
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/6164/C
来源:牛客网
题目描述
牛牛为了减(吃)肥(好),希望对他的零食序列有更深刻的了解,所以他把他的零食排成一列,然后对每一个零食的美味程度都打了分,现在他有可能执行两种操作:
eat k:吃掉当前的第k个零食。右边的零食全部往左移动一位(编号减一)。
query i j:查询当前第i个零食到第j个零食里面美味度最高的和最低的零食的美味度。
输入描述:
第一行包含两个数n, m,表示原始数组的元素个数和操作的个数。第二行包括n个数,表示原始数组。以下m行,每行格式为1 k或者2 i j,其中第一个数为1表示吃掉,为2表示询问。
输出描述:
对每个询问操作输出一行,包括两个数,表示该范围内的最小值和最大值。
示例1
输入
复制
10 4
1 5 2 6 7 4 9 3 1 5
2 2 8
1 3
1 6
2 2 8
输出
复制
2 9
1 7
说明
1<=n, m<=1e6, 1<=m<=1e6,数组中的元素绝对值均不超过1e9
备注:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
ll x;
ll maxx[maxn << 2], minn[maxn << 2], tr[maxn << 2];
const int inf = 0x3f3f3f3f;
#define lson p << 1, l, mid
#define rson p << 1 | 1, mid + 1, r
void pushup(ll p)
{
maxx[p] = max(maxx[p << 1], maxx[p << 1 | 1]);
minn[p] = min(minn[p << 1], minn[p << 1 | 1]);
tr[p] = tr[p << 1] + tr[p << 1 | 1];
}
void build(ll p, ll l, ll r)
{
if (l == r)
{
scanf("%lld", &x);
maxx[p] = minn[p] = x;
tr[p] = 1;
return;
}
ll mid = (l + r) >> 1;
build(lson);
build(rson);
pushup(p);
}
void del(ll o, ll p, ll l, ll r)
{
if (l == r)
{
tr[p] = 0;
minn[p] = inf;
maxx[p] = -inf;
return;
}
ll mid = (l + r) >> 1;
if (o <= mid)
del(o, lson);
else
del(o, rson);
pushup(p);
}
ll qmin(ll ql, ll qr, ll p, ll l, ll r)
{
if (ql <= l && r <= qr)
{
return minn[p];
}
ll mid = (l + r) >> 1;
ll ans = inf;
if (ql <= mid)
{
ans = min(ans, qmin(ql, qr, lson));
}
if (qr > mid)
{
ans = min(ans, qmin(ql, qr, rson));
}
return ans;
}
ll qmax(ll ql, ll qr, ll p, ll l, ll r)
{
if (ql <= l && r <= qr)
{
return maxx[p];
}
ll mid = (l + r) >> 1;
ll ans = -inf;
if (ql <= mid)
{
ans = max(ans, qmax(ql, qr, lson));
}
if (qr > mid)
{
ans = max(ans, qmax(ql, qr, rson));
}
return ans;
}
ll qid(ll p, ll l, ll r, ll o)
{
if (l == r)
{
return l;
}
ll mid = (l + r) >> 1;
if (tr[p << 1] >= o)
return qid(lson, o);
else
return qid(rson, o - tr[p << 1]);
}
int main()
{
ll n, m;
scanf("%lld%lld", &n, &m);
build(1, 1, n);
int op, x, y;
ll pos, posr;
while (m--)
{
scanf("%d", &op);
if (op == 1)
{
scanf("%d", &x);
pos = qid(1, 1, n, x);
del(pos, 1, 1, n);
}
else
{
scanf("%d%d", &x, &y);
pos = qid(1, 1, n, x);
posr = qid(1, 1, n, y);
printf("%lld %lld\n", qmin(pos, posr, 1, 1, n), qmax(pos, posr, 1, 1, n));
}
}
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/6164/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
题目描述
牛牛为了奖励自己减肥成功( 并没有),奖励自己去X市旅游,X市有N个地点,这些点之间有M条长度不同的边,他们组成了一张有向无环图,牛牛希望从一个点X到另外一个点Y走密度最小的一条路,所谓密度是指的从X到Y的总路程长度除以X到Y走过的边的数量。现在牛牛提出Q个询问,每次询问一对Xi,Yi,请你输出Xi到Yi密度最小的路径密度。
输入描述:
第一行包括2个整数N和M。
以下M行,每行三个数字u、v、w,表示从u点到v点有一条权值为w的有向边。
再下一行有一个整数Q。
以下Q行,每行一个询问X和Y,求X到Y的最小密度路径
输出描述:
对于每个询问输出一行,表示该询问的最小密度路径的密度(误差在1e-3范围内即可),如果不存在这么一条路径输出“OMG!”(不含引号)。
示例1
输入
复制
3 3
1 3 5
2 1 6
2 3 6
2
1 3
2 3
输出
复制
5.000
5.500
说明
1 ≤ N ≤ 50,1 ≤ M ≤ 1000,1 ≤ W ≤ 100000,1 ≤ Q ≤ 100000。
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
#include <climits>
#include <stack>
#include <map>
#include <cmath>
#include <set>
using namespace std;
typedef long long ll;
const int mod = 1e4 + 7;
const int inf = 0x3f3f3f3f;
int dp[60][60][60];
double ans[60][60];
template <class T>
void read(T &x)
{
ll f = 1;
x = 0;
char c = getchar();
while (!isdigit(c))
{
f = -1;
c = getchar();
}
while (isdigit(c))
{
x = x * 10 + c - 48;
c = getchar();
}
x *= f;
}
template <class T>
void write(T x)
{
if (x < 0)
{
putchar('-');
x = -x;
}
if (x > 9)
{
write(x / 10);
}
putchar(x % 10 + '0');
}
int main()
{
int n, m;
read(n);
read(m);
int u, v, w;
memset(dp, 0x3f, sizeof(dp));
for (int i = 1; i <= n; i++)
{
dp[i][i][0] = 0;
}
for (int i = 0; i < m; i++)
{
read(u);
read(v);
read(w);
dp[u][v][1] = min(w, dp[u][v][1]);
}
for (int p = 2; p <= n; p++)
{
for (int k = 1; k <= n; k++)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
dp[i][j][p] = min(dp[i][j][p], dp[i][k][p - 1] + dp[k][j][1]);
}
}
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
ans[i][j] = inf;
if (i == j)
continue;
for (int p = 1; p <= n; p++)
{
if (dp[i][j][p] < inf)
{
ans[i][j] = min(ans[i][j], dp[i][j][p] * 1.0 / p);
}
}
}
}
int q;
read(q);
while (q--)
{
read(u);
read(v);
if (ans[u][v] < inf)
printf("%.3f\n", ans[u][v]);
else
printf("OMG\n");
}
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/6164/E
来源:牛客网
题目描述
旅行完了的牛牛又胖了,于是他终于下决心要戒掉零食,所以他带着他最爱的土豆回到了牛星,开始了在牛星种土豆和只吃土豆减肥的日子。(吃土豆能减肥么?)经过了辛勤的劳作,牛牛种的土豆奇迹般的收获了,于是他得到了很多很多很多很多的土豆(实在太多,数不过来了,你可以认为是无穷个)。他将这很多很多个土豆按照重量从小到大进行了排序,每个土豆的编号依次为1、2、3……N,然后他就惊奇地发现:由于牛星球的土壤很奇特,第i个土豆的重量正好是3^(i-1) 。
现在牛牛饿了要吃掉其中的若干个土豆。他每次拿的土豆的数目是任意的,选的土豆也是任意的。选中的土豆的总重量即每个土豆重量之和。例如:牛牛这一次拿了第一个土豆和第三个土豆,那么总重量为1+9=10。
牛牛想知道,在所有的选土豆方案里,他可以获得的第k大的“总重量”是多少。
输入描述:
有多组输入样例。
第一行是一个整数T,表示有T组测试样例,0 ≤ T ≤ 70。
之后的T行中,每一行有一个数字k。(k<=2^31-1)
输出描述:
针对每一个测试样例,输出一行;格式为:
“Case #$Num:
A
”
,
其
中
,
A”,其中,
A”,其中,N表示第Num组样例,$A表示他可以获得的第k大的总重量。
示例1
输入
复制
2
7
4
输出
复制
Case #1: 13
Case #2: 9
说明
土豆的重量依次为:1,3,9,27,81……
牛牛能够拿到的重量从小到大为:
1、3、4(=1+3)、9、10(=1+9)、12(=9+3)、13(=1+9+3)……
所以第7大的美观程度是13,第四大是9
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll solve(ll x){
ll ans=0,t=1;
while(x){
if(x&1)ans+=t;
t*=3;
x>>=1;
}
return ans;
}
int main(){
ll t,a;
cin>>t;
for(int i=1;i<=t;i++){
cin>>a;
printf("Case #%d: %lld\n",i,solve(a));
}
return 0;
}