CSU 1813: 盖房子 1815: Enterprising Escape 1817: Bones’s Battery 1818: Crusher’s Code

1813: 盖房子

#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-9;
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int N = 1e3 + 10;
char s[N];
int n, m;
int c[N][N], a[N][N];
LL ls[N][N], lx[N][N], rs[N][N], rx[N][N];

void GetFour()
{
	memset(c, 0, sizeof(c));
	rep(i, 1, n)
	{
		rep(j, 1, m)
		{
			if (a[i][j] || c[i][j]) continue;
			while (c[i][j] <= n - i && !a[i + c[i][j]][j]) c[i][j]++;
			rep(k, 2, c[i][j]) c[i + k - 1][j] = c[i][j] - k + 1;
		}
		int sum = 0;  stack<pii> p;
		per(j, m, 1)
		{
			pii now = mp(c[i][j], 1);
			while (!p.empty() && p.top().ff > now.ff)
			{
				pii q = p.top();  sum -= q.ff * q.ss;
				now.ss += q.ss;   p.pop();
			}
			sum += now.ff * now.ss;
			p.push(now);
			ls[i][j] = sum;
		}
		sum = 0; while (!p.empty()) p.pop();
		rep(j, 1, m)
		{
			pii now = mp(c[i][j], 1);
			while (!p.empty() && p.top().ff > now.ff)
			{
				pii q = p.top();  sum -= q.ff * q.ss;
				now.ss += q.ss;   p.pop();
			}
			sum += now.ff * now.ss;
			p.push(now);
			rs[i][j] = sum;
		}
	}
	memset(c, 0, sizeof(c));
	per(i, n, 1)
	{
		rep(j, 1, m)
		{
			if (a[i][j] || c[i][j]) continue;
			while (c[i][j] < i && !a[i - c[i][j]][j]) c[i][j]++;
			rep(k, 2, c[i][j]) c[i - k + 1][j] = c[i][j] - k + 1;
		}
		int sum = 0;  stack<pii> p;
		per(j, m, 1)
		{
			pii now = mp(c[i][j], 1);
			while (!p.empty() && p.top().ff > now.ff)
			{
				pii q = p.top();  sum -= q.ff * q.ss;
				now.ss += q.ss;   p.pop();
			}
			sum += now.ff * now.ss;
			p.push(now);
			lx[i][j] = sum;
		}
		sum = 0; while (!p.empty()) p.pop();
		rep(j, 1, m)
		{
			pii now = mp(c[i][j], 1);
			while (!p.empty() && p.top().ff > now.ff)
			{
				pii q = p.top();  sum -= q.ff * q.ss;
				now.ss += q.ss;   p.pop();
			}
			sum += now.ff * now.ss;
			p.push(now);
			rx[i][j] = sum;
		}
	}
}

int main()
{
	while (scanf("%d%d", &n, &m) != EOF)
	{
		rep(i, 0, n + 1) rep(j, 0, m + 1) ls[i][j] = rs[i][j] = 0;
		rep(i, 1, n)
		{
			scanf("%s", s + 1);
			rep(j, 1, m) a[i][j] = s[j] - '0';
		}
		GetFour();
		LL L = 0, R = 0, ans = 0;
		rep(i, 1, n)
		{
			rep(j, 1, m) (R += ls[i][j]) %= mod;
			(ans += L * R) %= mod;        R = 0;
			rep(j, 1, m) (L += rx[i][j]) %= mod;
		}
		L = R = 0;
		rep(j, 1, m) 
		{
			rep(i, 1, n) (R += ls[i][j]) %= mod;
			(ans += L * R) %= mod;        R = 0;
			rep(i, 1, n) (L += rx[i][j]) %= mod;
		}
		rep(i, 1, n)
		{
			rep(j, 1, m)
			{
				rx[i][j] += rx[i - 1][j] + rx[i][j - 1] - rx[i - 1][j - 1];
				(ans -= rx[i][j] * ls[i + 1][j + 1]) %= mod;
			}
			per(j, m, 1)
			{
				lx[i][j] += lx[i - 1][j] + lx[i][j + 1] - lx[i - 1][j + 1];
				(ans -= lx[i][j] * rs[i + 1][j - 1]) %= mod;
			}
		}
		printf("%lld\n", (ans + mod) % mod);
	}
	return 0;
}

1815: Enterprising Escape

#include <iostream>
#include <cstring>
#include <stack>
#include <cstdio>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
const double eps=1e-8;
const double PI=acos(-1.0);
using namespace std;

struct st{
    int x;
    int y;
    int step;
    friend bool operator <(st a,st b){
    return a.step>b.step;}
}node;
char a[1005][1005];
int v[1005][1005];
int d[][2]={{1,0},{0,1},{0,-1},{-1,0}};
int k,n,m,num;
 map<char,int> s;
int bfs(int x,int y)
{
    priority_queue<st>q;
    node.x=x;
    node.y=y;
    node.step=0;
    q.push(node);
    v[x][y]=1;
    while(!q.empty())
    {
        st tem=q.top();
        //cout<<tem.x<<" "<<tem.y<<endl;
        q.pop();
        st tp;
         if(tem.x>=m-1||tem.y>=n-1||tem.x<=0||tem.y<=0)
            {

                return tem.step;//cout<<"t:"<<e<<endl;

            }
        for(int i=0; i<4; i++)
        {
            tp.x=tem.x+d[i][0];
            tp.y=tem.y+d[i][1];

            if(v[tp.x][tp.y]) continue;

            tp.step=tem.step+s[a[tp.x][tp.y]];
            q.push(tp);
            v[tp.x][tp.y]=1;
            //cout<<tp<<endl;
        }
    }
    return -1;
}
int main()
{
    int t;

    scanf("%d",&t);
    while(t--){
            memset(v,0,sizeof(v));
        char c;
        scanf("%d%d%d",&k,&n,&m);
        getchar();
        for(int i=0;i<k;i++){
            scanf("%c %d",&c,&num);
            getchar();
            s[c]=num;
            }
            int x,y;
        for(int i=0;i<m;i++)
            scanf("%s",a[i]);
            for(int i=0;i<m;i++)
                for(int j=0;j<n;j++)
                if(a[i][j]=='E'){
                    x=i;y=j;
                }
           printf("%d\n",bfs(x,y));

    }
    return 0;
}

1817: Bones’s Battery

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<math.h>
#include<map>
#include<queue> 
#include<algorithm>

using namespace std;

const double pi=acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn=100005;
const double eps=1e-8; 
const long long INF=10000000000;

int n,k,m;
long long dis[105][105], red[105][105]; 

void init(long long dis[][105]){//初始化数组 
    for (int i=0;i<n;i++){
        for (int j=0;j<n;j++){
            if (i==j)dis[i][j]=0;
            else dis[i][j]=INF;
        }
    }
}

void floyd(long long dis[][105]){//folyd 求各源点间的最短距离 
    for(int t=0;t<n;t++){
        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                dis[i][j]=min(dis[i][j],dis[i][t]+dis[t][j]);
            }
        }
    }
}

int main()
{
    int t;
    scanf ("%d",&t);
    while (t--){
        scanf ("%d%d%d",&n,&k,&m);
        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                if (i==j)dis[i][j]=0;
                else dis[i][j]=INF;
            }
        }
        int u,v,val;
        for (int i=0;i<m;i++){
            scanf ("%d%d%d",&u,&v,&val);
            dis[u][v]=dis[v][u]=val;
        }
        floyd(dis);
        long long lo=1,hi=INF;
        long long mid;
        long long ans=INF;
        while (lo<=hi){//二分答案 
            mid=(lo+hi)/2;
            init(red);
            for (int i=0;i<n;i++){
                for (int j=0;j<n;j++){
                    red[i][j]= dis[i][j]<=mid?1:INF;//如果小于mid说明i->j只需要充一次电 
                }
            }
            floyd(red);//跑floyd 
            long long d=0;
            for (int i=0;i<n;i++){
                for (int j=0;j<n;j++){
                    if (red[i][j]>d)d=red[i][j];//求出充电次数最多的一条路径 
                }
            }
            if (d<=k){//如果次数小于k说明此时的距离符合 
                ans=mid;//保存 
                hi=mid-1;
            }
            else lo=mid+1;
        }
        printf ("%lld\n",ans);//输出 
    }
    return 0;
 } 

1818: Crusher’s Code

#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
int n;
int A[10];
void init(){
	int B[10], v[105], sz = 0;
	memcpy(B, A, sizeof(A));
	memset(v, -1, sizeof(v));
	sort(B, B + n);
	for (int i = 0; i<n; i++)
	if (v[B[i]] == -1) v[B[i]] = sz++;
	for (int i = 0; i<n; i++) {
		A[i] = v[A[i]];
	}
}

int get_sta(int A[]){
	int ret = 0;
	for (int i = 0; i<n; i++) ret = ret * 8 + A[i];
	return ret;
}

void get_arr(int S, int A[]){
	for (int i = n - 1; i >= 0; i--){
		A[i] = S % 8;
		S /= 8;
	}
}

const int MX = 1e5 + 5;
map<int, int>vis;
int sz, S[MX];
void bfs(int s){
	vis.clear();
	queue<int>q;
	q.push(s);
	vis[s] = 1;
	while (!q.empty()){
		int u = q.front(); q.pop();
		get_arr(u, A);
		for (int i = 0; i<n; i++)
		for (int j = i + 1; j<n; j++)
		if (A[i]>A[j]){
			swap(A[i], A[j]);
			int SS = get_sta(A);
			if (vis[SS] == 0){
				q.push(SS);
				vis[SS] = 1;
			}
			swap(A[i], A[j]);
		}
	}
	sz = 0;
	for (map<int, int>::iterator it = vis.begin(); it != vis.end(); it++) {
		S[sz] = it->first;
		it->second = sz++;
	}
}

double dp[MX];

//递推写法
double DP1(){
	memset(dp, 0, sizeof(dp));
	for (int k = 0; k<sz; k++){
		int success = 0;
		int sta = S[k];
		get_arr(sta, A);
		for (int i = 0; i<n; i++)
		for (int j = 0; j<n; j++){
			int l = min(i, j), r = max(i, j);
			if (A[l]>A[r]){
				swap(A[l], A[r]);
				int SS = get_sta(A);
				success++;
				dp[k] += dp[vis[SS]] / (n*n);
				swap(A[l], A[r]);
			}
		}
		if (success>0) dp[k] = (dp[k] + 1)*n*n / success;
	}
	return dp[sz - 1];
}

double DP2(){
	memset(dp, 0, sizeof(dp));
	for (int k = 0; k<sz; k++){
		int success = 0;
		int sta = S[k];
		get_arr(sta, A);
		for (int l = 0; l<n - 1; l++){
			int r = l + 1;
			if (A[l]>A[r]){
				swap(A[l], A[r]);
				int SS = get_sta(A);
				success++;
				dp[k] += dp[vis[SS]] / (n - 1);
				swap(A[l], A[r]);
			}
		}
		if (success>0) dp[k] = (dp[k] + 1)*(n - 1) / success;
	}
	return dp[sz - 1];
}

//记忆化搜索写法
double DP1(int u){
	if (u == 0) return dp[u] = 0;
	if (dp[u] >= 0) return dp[u];
	int sta = S[u];
	get_arr(sta, A);
	int success = 0;
	dp[u] = 0;
	for (int i = 0; i<n; i++){
		for (int j = 0; j<n; j++){
			int l = min(i, j), r = max(i, j);
			if (A[l]>A[r]){
				swap(A[l], A[r]);
				int SS = get_sta(A);
				success++;
				dp[u] += DP1(vis[SS]) / (n*n);
				swap(A[l], A[r]);
			}
		}
	}
	if (success>0) dp[u] = (dp[u] + 1)*n*n / success;
	return dp[u];
}

double DP2(int u){
	if (u == 0) return dp[u] = 0;
	if (dp[u] >= 0) return dp[u];
	int sta = S[u];
	get_arr(sta, A);
	int success = 0;
	dp[u] = 0;
	for (int i = 0; i<n - 1; i++){
		int l = i, r = i + 1;
		if (A[l]>A[r]){
			swap(A[l], A[r]);
			int SS = get_sta(A);
			success++;
			dp[u] += DP2(vis[SS]) / (n - 1);
			swap(A[l], A[r]);
		}
	}
	if (success>0) dp[u] = (dp[u] + 1)*(n - 1) / success;
	return dp[u];
}

int main(){
	int T;
	scanf("%d", &T);
	while (T--){
		scanf("%d", &n);
		for (int i = 0; i<n; i++) scanf("%d", &A[i]);
		init();
		int init_sta = get_sta(A);
		bfs(init_sta);

		for (int i = 0; i<sz; i++) dp[i] = 0;
		double ans1 = DP1();
		for (int i = 0; i<sz; i++) dp[i] = 0;
		double ans2 = DP2();

		printf("Monty %.6f Carlos %.6f\n", ans1, ans2);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/nameofcsdn/article/details/80314072
今日推荐