CSU 1807: 最长上升子序列~ 1808: 地铁 1809: Parenthesis 1811: Tree Intersection 1812: 三角形和矩形

1807: 最长上升子序列~

#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define rep(i,j,k) for (int i = j; i <= k; i++)
#define per(i,j,k) for (int i = j; i >= k; i--)
#define loop(i,j,k) for (int i = j;i != -1; i = k[i])
#define lson x << 1, l, mid
#define rson x << 1 | 1, mid + 1, r
#define ff first
#define ss second
#define mp(i,j) make_pair(i,j)
#define pb push_back
#define pii pair<int,int>
#define in(x) scanf("%d", &x);
using namespace std;
typedef long long LL;
const int low(int x) { return x&-x; }
const double eps = 1e-8;
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
int n, a[N];
LL dp[N];

void init()
{
	dp[0] = dp[1] = 0; rep(i, 2, N - 1) dp[i] = dp[i - 1] + 2 * i - 3;
}

int check(int x)
{
	int now = 1;
	rep(i, 1, n)
	{
		if (now == a[x]) ++now;
		if (i == x) continue;
		if (a[i] && a[i] != now) return 0;
		++now;
	}
	return 1;
}

int check(int x, int y)
{
	if (x != y - 1) return 0;
	rep(i, 1, n)
	{
		if (i == x || i == y) continue;
		if (a[i] && a[i] != i) return 0;
	}
	return 1;
}

LL get(int x, int y)
{
	int l = n + 1, r = 0;
	rep(i, 1, n) if (a[i] && a[i] != i) l = min(l, i), r = max(r, i);
	rep(i, l, r) if (a[i] && a[i] == i) return 0;
	int L = l, R = n - r + 1;
	per(i, l, 1) if (a[i] == i) { L = l - i; break; }
	rep(i, r, n) if (a[i] == i) { R = i - r; break; }
	return 1LL * (L - x) * (R - y);
}

LL get()
{
	LL res = 0, now = 0;
	rep(i, 1, n) if (a[i]) res += dp[a[i] - now - 1], now = a[i];
	return res + dp[n - now];
}

int main()
{
	init();
	while (scanf("%d", &n) != EOF)
	{
		int flag = 0, l = 0, r = 0;
		rep(i, 1, n)
		{
			scanf("%d", &a[i]);
			if (!a[i]) continue;
			if (abs(a[i] - i) > 1) flag = i;
			if (a[i] - i == 1) l = i;
			if (i - a[i] == 1) r = i;
		}
		if (flag) { printf("%d\n", check(flag)); continue; }
		if (l&&r) { printf("%d\n", check(l, r)); continue; }
		if (l || r) { printf("%lld\n", get(!l, !r)); continue; }
		printf("%lld\n", get());
	}
	return 0;
}

1808: 地铁

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn =255555;
const int INF = 0x3f3f3f3f; 

int n,m;
struct Edge{
    int to,next;
    int w;
}edge[maxn*2];

int head[maxn],tot;

void init(){
    memset(head,-1,sizeof(head));
    tot=0;
}
void addedge(int u,int v,int w){

    edge[tot].to=v;
    edge[tot].next = head[u];
    edge[tot].w =w;
    head[u]=tot++;  
}

vector<int>num[maxn];
map<int,int>mp[maxn];

int dis[maxn];
int cnt;
struct node{
    int now;
    int c;
    node(int  _now = 0,int _c=0):now(_now),c(_c){}
    bool operator <(const node &r)const
    {
        return c>r.c;
    }
};
void DJ(){

    priority_queue<node> que;
    while(!que.empty()) que.pop();
    for(int i=1;i<cnt;++i) dis[i]=INF;
    for(int i=0;i<num[1].size();++i){
        int st;
        st = mp[1][num[1][i]];
        dis[st]=0;
        que.push(node(st,0));
    } 
    node temp;
    while(!que.empty()){

        temp = que.top();
        que.pop();
        int u = temp.now;
        int cost = temp.c;
        if(cost>dis[u])
        continue;

        for(int i=head[u];~i;i=edge[i].next){

            int v = edge[i].to;
            int w = edge[i].w;
            if(dis[v]>cost+w){
                dis[v]= cost + w;
                que.push(node(v,dis[v]));
            }
        }
    }
}

int main(){

    int u,v,w,x;
    while(scanf("%d%d",&n,&m)!=EOF){

        init();
        cnt=1;
        for(int i=1;i<=n;i++){
            num[i].clear();
            mp[i].clear();
        }
        for(int i=0;i<m;++i){
            scanf("%d%d%d%d",&u,&v,&x,&w);
            if(!mp[u][x]){
                mp[u][x]=cnt++;
                num[u].push_back(x);
            }
            u=mp[u][x];
            if(!mp[v][x]){
                mp[v][x]=cnt++;
                num[v].push_back(x);
            }
            v=mp[v][x];
            addedge(u,v,w);
            addedge(v,u,w);
        }
        for(int i=1;i<=n;i++){
            sort(num[i].begin(),num[i].end());
            for(int j=0;j<num[i].size()-1;++j){

                u=mp[i][num[i][j]];
                v=mp[i][num[i][j+1]];

                w=num[i][j+1]-num[i][j]; //同一站点不同线路的拆点之间的差值 
                addedge(u,v,w);
                addedge(v,u,w);

            }
        }
        DJ();
        int ans=INF;
        for(int i=0;i<num[n].size();i++){
            u=mp[n][num[n][i]];
            ans=min(ans,dis[u]);

        }
        printf("%d\n",ans);
    }
    return 0;
}

1809: Parenthesis

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
#define lld %I64d
#define REP(i,k,n) for(int i=k;i<n;i++)
#define REPP(i,k,n) for(int i=k;i<=n;i++)
#define scan(d) scanf("%d",&d)
#define scanl(d) scanf("%I64d",&d)
#define scann(n,m) scanf("%d%d",&n,&m)
#define scannl(n,m) scanf("%I64d%I64d",&n,&m)
#define mst(a,k)  memset(a,k,sizeof(a))
#define LL long long
#define N 1005
#define mod 1000000007
inline int read(){int s=0;char ch=getchar();for(; ch<'0'||ch>'9'; ch=getchar());for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0';return s;}

char s[100005];
int sum[100005];
struct node
{
    int l,r,val;
}seg[100005*4];

void build(int i,int l,int r)
{
    seg[i].l=l;
    seg[i].r=r;
    if(l==r)
    {
        seg[i].val = sum[l];
        return ;
    }
    int mid = (l+r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    seg[i].val = min(seg[i<<1].val,seg[i<<1|1].val);
}

int query(int i,int l,int r)
{
    if(l<=seg[i].l && r>=seg[i].r)
    {
       return seg[i].val;
    }
    int ret = 1e9;
    int mid = (seg[i].l+seg[i].r)>>1;
    if(mid>=l) ret = min(ret,query(i<<1,l,r));
    if(mid<r)  ret = min(ret,query(i<<1|1,l,r));
    return ret;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,q;
    while(~scann(n,q))
    {
        scanf("%s",s+1);
        mst(sum,0);
        REPP(i,1,n)
            if(s[i]=='(') sum[i] = sum[i-1] + 1;
            else sum[i] = sum[i-1] - 1;
        build(1,1,n);
        while(q--)
        {
            int l,r;
            scann(l,r);
            if(l>r) swap(l,r);
            if(s[l] == s[r] || s[l]==')')
                puts("Yes");
            else if(l==1 || r==n)
                puts("No");
            else
            {
                int ret = query(1,l,r-1);
                if(ret<2) puts("No");
                else    puts("Yes");
            }
        }
    }

    return 0;
}

1811: Tree Intersection

#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define rep(i,j,k) for (int i = j; i <= k; i++)
#define per(i,j,k) for (int i = j; i >= k; i--)
#define loop(i,j,k) for (int i = j;i != -1; i = k[i])
#define lson x << 1, l, mid
#define rson x << 1 | 1, mid + 1, r
#define ff first
#define ss second
#define mp(i,j) make_pair(i,j)
#define pb push_back
#define pii pair<int,LL>
#define in(x) scanf("%d", &x);
using namespace std;
typedef long long LL;
const int low(int x) { return x&-x; }
const double eps = 1e-9;
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
int n, col[N], x, y;
int ft[N], nt[N], u[N], v[N], sz;
int Ft[N], Nt[N], U[N], V[N], Sz;
int d[N], t, pre[N], L[N], R[N];
int f[N], ans[N];

void dfs(int x, int fa)
{
	d[pre[x] = ++t] = x;
	L[col[x]] = min(L[col[x]], t);
	R[col[x]] = max(R[col[x]], t);
	loop(i, ft[x], nt)
	{
		if (u[i] == fa) continue;
		dfs(u[i], x);
		U[Sz] = pre[u[i]];	V[Sz] = v[i];
		Nt[Sz] = Ft[t];	    Ft[t] = Sz++;
	}
}

void add(int x, int y)
{
	for (int i = x; i <= n; i += low(i)) f[i] += y;
}

int get(int x)
{
	int res = 0;
	for (int i = x; i; i -= low(i)) res += f[i];
	return res;
}

int main()
{
	while (scanf("%d", &n) != EOF)
	{
		Sz = sz = t = 0;
		rep(i, 1, n) in(col[i]);
		rep(i, 1, n) Ft[i] = ft[i] = -1;
		rep(i, 1, n) L[i] = n + 1, R[i] = f[i] = 0;
		rep(i, 1, n - 1)
		{
			in(x);	in(y);
			u[sz] = y; v[sz] = i; nt[sz] = ft[x];	ft[x] = sz++;
			u[sz] = x; v[sz] = i; nt[sz] = ft[y];	ft[y] = sz++;
		}
		dfs(1, 0);
		rep(i, 1, n) pre[i] = f[i] = 0;
		rep(i, 1, n)
		{
			add(pre[col[d[i]]] + 1, 1);	add(i + 1, -1); pre[col[d[i]]] = i;
			if (i == R[col[d[i]]]) add(1, -1), add(L[col[d[i]]] + 1, 1);
			loop(j, Ft[i], Nt) ans[V[j]] = get(U[j]);
		}
		rep(i, 1, n - 1) printf("%d\n", ans[i]);
	}
	return 0;
}

1812: 三角形和矩形

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define eps 1e-8
using namespace std;
struct point{
    double x,y;
}S[5],J[5],I[110];
struct Node{
    point a,b;
}A[5];
int sig(double n){
    if(fabs(n)<eps)return 0;
    else if(n>eps)return 1;
    else return -1;
}
bool judge(int a,int b){//判断线段相交 
    if(min(A[a].a.x,A[a].b.x)>max(A[b].a.x,A[b].b.x)||min(A[a].a.y,A[a].b.y)>max(A[b].a.y,A[b].b.y)||min(A[b].a.x,A[b].b.x)>max(A[a].a.x,A[a].b.x)||min(A[b].a.y,A[b].b.y)>max(A[a].a.y,A[a].b.y))
    return false;
    double h,i,j,k;
    h=(A[a].b.x-A[a].a.x)*(A[b].a.y-A[a].a.y)-(A[a].b.y-A[a].a.y)*(A[b].a.x-A[a].a.x);
    i=(A[a].b.x-A[a].a.x)*(A[b].b.y-A[a].a.y)-(A[a].b.y-A[a].a.y)*(A[b].b.x-A[a].a.x);
    j=(A[b].b.x-A[b].a.x)*(A[a].a.y-A[b].a.y)-(A[b].b.y-A[b].a.y)*(A[a].a.x-A[b].a.x);
    k=(A[b].b.x-A[b].a.x)*(A[a].b.y-A[b].a.y)-(A[b].b.y-A[b].a.y)*(A[a].b.x-A[b].a.x);
    return h*i<=eps&&j*k<=eps;
}
void getinter(point p1,point p2,point p3,point p4,point &inter){//求交点 
    inter=p1;
    double ans=((p1.x-p3.x)*(p3.y-p4.y)-(p1.y-p3.y)*(p3.x-p4.x))/((p1.x-p2.x)*(p3.y-p4.y)-(p1.y-p2.y)*(p3.x-p4.x));
    inter.x+=(p2.x-p1.x)*ans;
    inter.y+=(p2.y-p1.y)*ans;
}
double dist(point p1,point p2){  
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));  
}  
double cp(point p1,point p2,point p3){  
    return (p3.x-p1.x)*(p2.y-p1.y)-(p3.y-p1.y)*(p2.x-p1.x);  
}
bool cmp(point a,point b){  
    double ans=cp(I[0],a,b);  
    if(sig(ans)==0){  
        return dist(I[0],a)-dist(I[0],b)<=0;  
    }  
    else return ans>0;  
}  
int main()
{
    double x1,y1,x2,y2,x3,y3,x4,y4;
    while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4)!=EOF){
        S[0].x=x1;S[0].y=y1;S[1].x=x1;S[1].y=y2;S[2].x=x2;S[2].y=y1;
        J[0].x=x3;J[0].y=y3;J[1].x=x3;J[1].y=y4;J[2].x=x4;J[2].y=y4;J[3].x=x4;J[3].y=y3;
        int cnt=0;
        for(int i=0;i<3;++i){//矩形中包含的三角形的点 
            if(S[i].x>=min(x3,x4)&&S[i].x<=max(x3,x4)&&S[i].y>=min(y3,y4)&&S[i].y<=max(y3,y4)){
                I[cnt].x=S[i].x;I[cnt].y=S[i].y;cnt++;
            }
        }
        for(int i=0;i<4;++i){//三角形中包含的矩形中的点 
            if(J[i].x>=min(x1,x2)&&J[i].x<=max(x1,x2)&&J[i].y>=min(y1,y2)&&J[i].y<=max(y1,y2)){
                double k=(y1-y2)/(x2-x1);double b=y1-k*x2;
                if((sig(k*x1-y1+b)>=0&&sig(J[i].x*k-J[i].y+b)>=0)||(sig(k*x1-y1+b)<=0&&sig(J[i].x*k-J[i].y+b)<=0)){
                    I[cnt].x=J[i].x;I[cnt].y=J[i].y;cnt++;
                }
            }
        }
        for(int i=0;i<3;++i){
            for(int j=0;j<4;++j){//求出三角形和矩形的线段的交点 
                A[0].a=S[i];A[0].b=S[(i+1)%3];A[1].a=J[j];A[1].b=J[(j+1)%4];
                //printf("%lf %lf %lf %lf\n",J[j].x,J[j].y,J[(j+1)%4].x,J[(j+1)%4].y);
                if(judge(0,1)){
                    if(A[0].a.x==A[0].b.x&&A[0].a.x==A[1].a.x&&A[1].a.x==A[1].b.x)continue;
                    if(A[0].a.y==A[0].b.y&&A[0].a.y==A[1].a.y&&A[1].a.y==A[1].b.y)continue;
                   //printf("%lf %lf %lf %lf %lf %lf %lf %lf\n",A[0].a.x,A[0].a.y,A[0].b.x,A[0].b.y,A[1].a.x,A[1].a.y,A[1].b.x,A[1].b.y);
                    getinter(A[0].a,A[0].b,A[1].a,A[1].b,I[cnt]);cnt++;
                   // printf("%lf %lf\n",I[cnt-1].x,I[cnt-1].y);
                }
            }
        }
       // printf("%d\n",cnt);
        if(cnt<2){
            printf("0.00000000\n");
        }
        else {
        	int pos=0; 
        	for(int i=0;i<cnt;++i){  
            	if(I[pos].y>=I[i].y){  
                	if(I[pos].y==I[i].y){  
                    	if(I[pos].x>I[i].x)pos=i;  
                	}  
                	else pos=i;  
            	}  
        	}  
        	point temp=I[pos];I[pos]=I[0];I[0]=temp; 
            sort(I+1,I+cnt,cmp);//极角排序 
            double ans=0;
            for(int i=0;i<cnt;++i){//求多边形面积 
                double area=(I[(i+1)%cnt].x*I[i].y-I[(i+1)%cnt].y*I[i].x)/2.0;
                ans+=area;
            }
            printf("%.9lf\n",fabs(ans));
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/nameofcsdn/article/details/80313935