题意:输出2(2(2)+2+2(0))+2(2+2(0))+2(0)之类的等式的值,其中2(x)表示 2 x 2^{x} 2x,等式中只有0,2。
思路:
栈,或者eval
class Stack(object):
def __init__(self):
self.__list = []
def is_empty(self):
return self.__list == []
def push(self, item):
self.__list.append(item)
def pop(self):
if self.is_empty():
return
else:
return self.__list.pop()
def top(self):
if self.is_empty():
return
else:
return self.__list[-1]
def pow(a, b):
res = 1
while b:
if b & 1:
res = res * a
a = a * a
b >>= 1
return res
if __name__ == '__main__':
x = input("")
lenx = len(x)
s = Stack()
for i in range(0, lenx):
if x[i] == '2':
s.push(2)
elif x[i] == '0':
s.push(0)
elif x[i] == "(":
s.push(-1)
elif x[i] == ')':
a = s.top()
s.pop()
b = s.top()
s.pop()
while b >= 0:
a = a + b
b = s.top()
s.pop()
b = s.top()
s.pop()
b = pow(b, a)
s.push(b)
a = s.top()
s.pop()
while not s.is_empty():
b = s.top()
s.pop()
a = a + b
print(a)
或者
print(eval(input().replace("(","**(")))
题意:n天,每天 k i k_{i} ki件衣服选一件,每件衣服有一个属性。选m天,使得这m天里衣服的最大值-最小值最小。
思路:滑动窗口。将衣服按照价值排序,队列中保持m天的衣服,如果多余m天的就从队首pop,然后将下一件衣服加入队尾。
#include
#include
#include
#include
#include
#include
using namespace std;
const int N = 2e6 + 10;
struct PX{
int v, id;
PX (){}
PX (int x, int y)
{
v = x; id = y;
}
bool operator < (const PX & other)
const { return v < other.v ;}
}h[N];
int vist[N];
int main()
{
int n,m,cnt = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
{
int k;
scanf("%d", &k);
for(int j = 1; j <= k; j++)
{
int x;
scanf("%d",&x);
h[++cnt] = PX(x, i);
}
}
sort(h + 1, h + cnt + 1);
int now = 0;
int head = 1;
int tail = 0;
int ans = 1e9 + 10;
int px;
for(int i = 1; i <= cnt; i++)
{
tail ++;
px = h[tail].id;
vist[px]++;
if(vist[px] == 1)
now ++;
if(now >= m)
ans = min(ans, h[tail].v - h[head].v);
while(head <= tail && now >= m)
{
px = h[head].id;
vist[px] --;
if(!vist[px]) now --;
head++;
}
}
printf("%d\n",ans);
return 0;
}
题意:给一个凸多边形,一条确定方向和长度的线段(但是位置任意)。凸多边形绕原点旋转,求直线可以将多边形切成两半的概率。
思路:暴力枚举角度,旋转线段,求交点,计算距离。
#include
#include
#include
#include
#include
#include
#define double long double
using namespace std;
const int N = 7e4 + 10;
const double pi = 3.14159265358979323;
const double eps = 1e-8;
struct POINT{
double x,y;
POINT(){}
POINT(double a, double b){ x = a; y = b;}
}p[N * 4], sc[2], nowsc[2];
POINT operator - (POINT a, POINT b){return POINT(a.x - b.x, a.y - b.y);}
double CJ(POINT a,POINT b){return a.x * b.y - a.y * b.x;}
double get_k(POINT a, POINT b){ return (b.y - a.y) / (b.x - a.x); }
POINT get_node(POINT a, POINT b, POINT c, POINT d)
{
double A0 = a.y - b.y, B0 = b.x - a.x, C0 = a.x * b.y - a.y * b.x;
double A1 = c.y - d.y, B1 = d.x - c.x, C1 = c.x * d.y - c.y * d.x;
double D = A0 * B1 - A1 * B0;
return POINT((B0 * C1 - C0 * B1) / D, (A1 * C0 - A0 * C1) / D);
}
double get_dist(POINT a, POINT b){ return sqrt((a.x - b.x) * (a.x - b. x) + (a.y - b.y) * (a.y - b.y));}
POINT rotate(POINT a, double ang){return POINT(a.x * cos(ang) - a.y * sin(ang), a.x * sin(ang) + a.y * cos(ang));}
int main()
{
int n;
double L;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%Lf%Lf", &p[i].x, &p[i].y);
p[i + n] = p[i];
p[i + n * 2] = p[i];
p[i + n * 3] = p[i];
}
scanf("%Lf", &L);
for(int i = 0; i <= 1; i++)
scanf("%Lf%Lf", &sc[i].x, &sc[i].y);
int l = 1, r = 1;
int cnt = 0, tot = 3e5;
double k1, k2;
POINT p1, p2;
for(int i = 0; i < tot; i++)
{
double angle = 1.0 * i / tot * 2.0 * pi;
nowsc[0] = rotate(sc[0], angle);
nowsc[1] = rotate(sc[1], angle);
while(l < 4 * n && CJ(nowsc[0] - nowsc[1], p[l + 1] - nowsc[0]) * CJ (nowsc[0] - nowsc[1], p[l] - nowsc[0]) >=0 )
l++;
if(l >= r)
r = l + 1;
while(r < 4 * n && CJ(nowsc[1] - nowsc[0], p[r + 1] - nowsc[1]) * CJ (nowsc[1] - nowsc[0], p[r] - nowsc[1]) >=0)
r++;
p1 = get_node(nowsc[1], nowsc[0], p[l + 1], p[l] );
p2 = get_node(nowsc[1], nowsc[0], p[r + 1], p[r] );
if(L - get_dist(p1, p2) < eps){ cnt++;}
}
double ans = 1.0 * cnt / tot;
printf("%.4Lf",ans);
return 0;
}
题意:给出一棵树,A从1向n点走,速度为1,走了t秒后,B从n点出发来追A,速度为2,A以1的速度躲。每一秒,A先行动,然后B行动。求A的最长生存时间。
思路:以n为根建树,从1向上走t步求出t秒时的位置。枚举t~n的每一个节点作为拐点,对于每一个拐点而言,最优状态是向下走到其最深的叶子节点。
#include
#include
#include
#include
#include
#include
using namespace std;
const int N = 1e5 + 10;
struct EDGE{
int to, nxt;
EDGE(){}
EDGE(int x, int y)
{
to = x;
nxt = y;
}
}edge[N * 2];
int len[N], t[N], fa[N];
int tot;
void addedge(int x, int y)
{
edge[++tot] = EDGE(y, t[x]);
t[x] = tot;
}
int dfs(int x, int f)
{
len[x] = 0;
for(int p = t[x]; p; p = edge[p].nxt)
{
int y = edge[p].to;
if(y != f)
{
dfs(y, x);
len[x] = max(len[x], len[y] + 1);
fa[y] = x;
}
}
return 0;
}
int main()
{
int n,t;
scanf("%d%d", &n, &t);
int x, y;
for(int i = 1; i < n; i++)
{
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
dfs(n, 0);
int pos = 1;
for(int i = 1; i <= t; i++)
{
if(pos == n)
break;
pos = fa[pos];
}
if(pos == n)
{
printf("0");
return 0;
}
x = pos;
int cnt = 0;
while(x != n)
{
cnt++;
x = fa[x];
}
x = pos;
int ncnt = 0;
int ans = 0;
while(x != n)
{
if((cnt - ncnt + 1) / 2 <= ncnt)
break;
y = cnt - 3 * ncnt;
if(len[x] > y)
ans = max(ans, y + ncnt);
else
ans = max(ans, (y + len[x] + 1) / 2 + ncnt);
ncnt++;
x = fa[x];
}
printf("%d",ans);
return 0;
}