2020杭电多校第四场1002、1004、1005,1011、1012、1007

12.Last Problem

题目传送门

Last Problem

思路

以n为中心,它的上下左右分别为a,b,c,d,同时n也是a的下,b的上,c的右,d的左
所以 a + c = b + d a+c=b+d ,令a=1,c=4,则b=2,d=3
然后逆序dfs构造即可

代码

#include<cstdio>
#include<iostream>
#include <cstring>
#include<algorithm>
using namespace std;
// #define TDS_ACM_LOCAL
const int N=2e3+9;
int m[N][N];
void dfs(int x, int y, int v){
    if(v<=0)    return ;
    if(m[x][y+1]!=v-1)    dfs(x,y+1,v-1);
    if(m[x-1][y]!=v-2)    dfs(x-1,y,v-2);
    if(m[x+1][y]!=v-3)    dfs(x+1,y,v-3);
    if(m[x][y-1]!=v-4)    dfs(x,y-1,v-4);
    m[x][y]=v;
    cout<<x<<" "<<y<<" "<<v<<endl;
    return ;
}

void solve(){
    int n;
    cin>>n;
    memset(m, 0, sizeof(m));
    dfs(1000,1000,n);
    return ;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    solve();
    return 0;
}

11.Kindergarten Physics

题目传送门

Kindergarten Physics

思路

很难得的没读错题目,同时想到了比萨斜塔实验,觉得d不会改变,并且观察到 1 0 6 10^{-6} 的误差在数据范围内似乎可以做( 1 a , b , d , t 0 100 1≤a,b,d,t0≤100 ),但是想到前几场觉得没这么简单,就没做了。。。。

直接输出d即可

代码

#include<cstdio>
#include<iostream>
#include <cstring>
#include<algorithm>
using namespace std;
// #define TDS_ACM_LOCAL
void solve(){
    int a, b, d, t;
    cin>>a>>b>>d>>t;
    cout<<d<<endl;
    return ;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    int T;
    cin>>T;
    while(T--)  solve();
    return 0;
}

2.Blow up the Enemy

题目传送门

Blow up the Enemy

思路

儿子肯定直接选价值最大的武器(即为最小次数打出100伤害),张三如果不选相同次数即可打出100伤害的武器就会输,所以我们统计武器中最快打出100伤害的武器的个数k, k / 2 n k/2n 即为儿子输的概率,求儿子赢的概念为 1 k / 2 1-k/2

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const double pi = acos(-1.0);
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
const int N=1009;
const int hea=100;
int n, time, k, mx;
double x, y, ans;
void solve(){
    int n;
    cin>>n;
    mx=INF;
    for(int i=0; i<n; i++){
        cin>>x>>y;
        time=ceil((hea-x)/x)*y;
        if(time<mx) mx=time, k=1;
        else if(time==mx)   k++;
    }
    ans=1.0-(double)(0.5*k/n);
    cout<<ans<<endl;
    return ;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    int T;
    cin>>T;
    while(T--)  solve();
    return 0;
}

5.Equal Sentences

题目传送门

Equal Sentences

题目大意

给你一个有n个单词的字符串,求“几乎相等”的字符串序列的个数
对于“几乎相等”的定义为:
1、两个字符串的多重集相等(即单词出现的次数相等)
2、每个单词的第i个在两个序列中出现的位置之差不超过1(暗示互换单词位置)

思路

因为位置之差不大于1,所以考虑交换相邻的两个单词来构造“几乎相等”(包括其本身)
在交换时,注意相同的单词不能交换,不能连着交换一个单词两次(例a, b, c不能交换成b,c,a)
其中dp[i]为前 i 个单词组成的“几乎相等”字符串的个数,所以dp[0]=dp[1]=1;
相邻两个单词相等,则不交换为dp[i]=dp[i-1];
不等交换,为dp[i]=(dp[i-1]+dp[i-2])%mod;

代码

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const double pi = acos(-1.0);
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
const int N=1e5 +9;
const int mod=1e9 +7;
int n, dp[N];
string s[N];
void solve(){
    cin>>n;
    dp[0]=dp[1]=1;
    for(int i=1; i<=n; i++){
        cin>>s[i];
        if(i>1){
            if(s[i]==s[i-1])    dp[i]=dp[i-1];
            else dp[i]=(dp[i-1]+dp[i-2])%mod;
        }
    }
    cout<<dp[n]<<endl;
    return ;
}   

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    int T;
    cin>>T;
    while(T--)  solve();
    return 0;
}

4.Deliver the Cake

题目传送门

Deliver the Cake

思路

L和R可以考虑将换手造成的时间消耗放在边权上,对于M可以考虑将M分成L和R两条路(默认优先L)
然后直接跑dijkstra就行,如果起点或者终点为M,需要创建边权为0的虚拟点代替

代码

#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#define ll long long
#define P pair<ll,int>
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+10, M=2e6+10;

int T,n,m,s,t,x;
int to[M],nxt[M],val[M],head[N],idx;
char c[N];
ll dis[N];
bool st[N];

inline void add(int a,int b,int c)
{
    to[idx]=b,nxt[idx]=head[a],val[idx]=c,head[a]=idx++;
}

void dijkstra()
{
    memset(st,false,sizeof st);
    memset(dis,INF,sizeof dis);
    priority_queue<P,vector<P>,greater<P>> heap;
    if(c[s]=='M') heap.push({0,0}), dis[0]=0;
    else heap.push({0,s}), dis[s]=0;
    
    while(heap.size())
    {
        P t=heap.top();
        heap.pop();
        
        int id=t.second;
        if(st[id]) continue;
        st[id]=true;
        
        for(int i=head[id];~i;i=nxt[i])
        {
            int j=to[i];
            if(dis[j]>dis[id]+val[i])
            {
                dis[j]=dis[id]+val[i];
                heap.push({dis[j],j});
            }
        }
    }
}

void solve(){
    idx=0;
    memset(head,-1,sizeof head);   
        
    scanf("%d%d%d%d%d",&n,&m,&s,&t,&x);
    scanf("%s",c+1);
    if(c[s]=='M')
        add(0,s,0), add(s,0,0), add(0,s+n,0), add(s+n,0,0);
    if(c[t]=='M')
        add(2*n+1,t,0), add(t,2*n+1,0), add(2*n+1,t+n,0), add(t+n,2*n+1,0);
    int u, v, val;
    for(int i=0; i<m; i++){
        cin>>u>>v>>val;
        if(c[u]==c[v] && (c[u]=='R'||c[u]=='L'))
            add(u,v,val), add(v,u,val);
        else if(c[u]==c[v] && c[u]=='M')
            add(u,v,val), add(v,u,val), add(u+n,v,val+x), add(v,u+n,val+x), add(u,v+n,val+x), add(v+n,u,val+x), add(u+n, v+n, val), add(v+n, u+n, val);
        else if((c[u]=='L' && c[v]=='R')||(c[u]=='R'&&c[v]=='L'))
            add(u,v,val+x), add(v,u,val+x);
        else if(c[u]=='L' && c[v]=='M')
            add(u,v,val), add(v,u,val), add(u,v+n,val+x), add(v+n, u, val+x);
        else if(c[u]=='R' && c[v]=='M')
            add(u,v,val+x), add(v,u,val+x), add(u,v+n,val), add(v+n, u, val);
        else if(c[u]=='M' && c[v]=='L')
            add(u,v,val), add(v,u,val), add(u+n,v,val+x), add(v, u+n, val+x);
        else if(c[u]=='M' && c[v]=='R')
            add(u,v,val+x), add(v,u,val+x), add(u+n,v,val), add(v, u+n, val);
    }
    dijkstra();
    if(c[t]=='M')   cout<<dis[2*n+1];
    else            cout<<dis[t];
    cout<<endl;
}

int main()
{
    scanf("%d",&T);
    while(T--)  solve();
    return 0;
}

Go Running

题目传送门

Go Running

思路

最小点覆盖+网络流,所以单独写了

题解传送门

Go Running题解

猜你喜欢

转载自blog.csdn.net/xmyrzb/article/details/107728140