2017 Multi-University Training Contest

来源:互联网 发布:windows10 ssd优化软件 编辑:程序博客网 时间:2024/06/03 20:18

第九场比赛队伍内部出现了很多沟通问题吧,导致我们队伍1小时45分钟才出题。没什么好说的,第一次跌出前300,有点失落,也有遗憾吧。


1005


缩点为DAG,则如果在拓扑序中出现了有两个及以上入度为0的点则不合法

#include <bits/stdc++.h>


using namespace std;


vector<int> e[2005]; 


bool flag;


bool vis[2005];
bool g[1005][1005];


void dfs(int id)
{
for(auto ep:e[id])
{
if(vis[ep]) continue;
vis[ep]=1;
dfs(ep);
}
}


int main()
{
int T,n,m,u,v;
cin>>T;

while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
e[i].clear();

for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
e[u].push_back(v);
}
   
memset(g,0,sizeof g);
flag = 1;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof vis);
vis[i]=1;
dfs(i);
int cnt = 0;
for(int j=1;j<=n;j++)
if(vis[j]) g[i][j]=1;


int cnt = 0;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
if(g[i][j] || g[j][i]) cnt++;
if(cnt == (n-1)*n/2) flag = 1;
else flag = 0;
if(flag) puts("I love you my love and our love save us!");
else puts("Light my fire!");
}
return 0;


1008


将b数组排序,取出最小的两项作为a_1,a_2a1,a2,删除a_1,a_2,a_1+a_2a1,a2,a1+a2,再取出最小项作为a_3a3,再删除a_3,a_1+a_3,a_2+a_3a3,a1+a3,a2+a3,再取出最小项作为a_4a4,依次列推。

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>


using namespace std;
#define ll long long
#define PQ priority_queue
#define MP make_pair
#define PB push_back
#define PF push_front
#define POB pop_back
#define POF pop_front
#define PRF first
#define PRS second
#define fr(x) freopen(x,"r",stdin)
#define fw(x) freopen(x,"w",stdout)
#define cls(ar,val) memset ( ar, val, sizeof ( ar ) )
#define debug(a) cerr<<#a<<"=="<<a<<endl
#define lp(loop,start,end) for ( int loop = start; loop < end; ++loop )
#define lpd(loop,start,end) for ( int loop = start; loop > end; --loop )
#define lpi(loop,start,end) for ( int loop = start; loop <= end; ++loop )
#define lpdi(loop,start,end) for ( int loop = start; loop >= end; --loop )
#define qmax(a,b) (((a)>(b))?(a):(b))
#define qmin(a,b) (((a)<(b))?(a):(b))
#define qabs(a) (((a)>=0)?(a):(-(a)))
const int inf = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
map<int,int> mp;
const int MAXN = 600;
const int MAXM = 251000;
map<int,int> nums;
int m,n;
vector<int> ans;
template<typename T> inline void read(T &x){
x=0;T f=1;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do x=x*10+ch-'0',ch=getchar();while(ch<='9'&&ch>='0');x*=f;
}


template<typename A,typename B> inline void read(A&x,B&y){read(x);read(y);}
template<typename A,typename B,typename C> inline void read(A&x,B&y,C&z){read(x);read(y);read(z);}
template<typename A,typename B,typename C,typename D> inline void read(A&x,B&y,C&z,D&w){read(x);read(y);read(z);read(w);}


void input()
{
    nums.clear();
    for (int i=1; i<=m; i++) {
        int temp;
        read(temp);
        nums[temp]++;
    }
}


void work() 
{
    ans.clear();
    for (auto& tt:nums) 
        while(tt.second!=0) 
{
            for (int temp:ans) 
                nums[temp+tt.first]--;
            ans.push_back(tt.first);
            tt.second--;
        }
        
    printf("%d\n",mp[m]);
    for (int i=0,endd = ans.size()-1; i<=endd; i++)
        if (i!=endd) printf("%d ",ans[i]);
        else printf("%d\n",ans[i]);
}


int main() 
{
    lpi(i,1,500) mp[i*(i+1)/2] =i;
    while (scanf("%d",&m)!=EOF) 
{
        input();
        work();
    }
    return 0;
}


1010


定义dp[i][j][k],k = 0,表示A串从0~i 的子串A[0,i],能否匹配B串从0~j的子串B[0,j];k = 1,表示A[0,i] + A[i]能否匹配B[0,j]。
转移时考虑几种特殊情况,"a*" 可以匹配 "" ,"a","aa"...,".*"可以匹配"","a","b","aa","bb"...,注意 ".*" 不能匹配 "ab"这种串。

#include <bits/stdc++.h>


using namespace std;


char s1[2505],s2[2505];


void make(char s[])
{
    int len = strlen(s);
    for(int j=3;j<len;j++)
{
        if(s[j]=='*'&&s[j-2]=='*'&&s[j-1]==s[j-3])
{
            for(int i=j-1;i<len;i++)
                s[i]=s[i+2];
            len-=2;
        }
    }
}


int main()
{
    int T;
    scanf("%d",&T);getchar();
    while(T--){
        gets(s1+1);
gets(s2+1);
        make(s2+1);
        int len1 = strlen(s1+1);
        int len2 = strlen(s2+1);
        s1[0]=s2[0]='#';
        int i=len1,j=len2;
        bool flag = 0;
while(i>=0 && j>=0)
{
if(i==0 && j==0)
{
flag = 1;
break;
}

if(s1[i] == s2[j])
{
i--;j--;
continue;
}

if(s2[j]=='.')
{
i--;j--;
continue;
}
if(s2[j]=='*')
{
if(s2[j-1]!='.'&&s2[j-1]!=s1[i])
{
j-=2;
continue;
}
if(s2[j-1]=='.')
{
int t=i;
while(s1[i]==s1[t]) i--;
j-=2;
continue;
}
if(s2[j-1]==s1[i])
{
int t=i;
while(s1[i]==s1[t]) i--;
j-=2;
continue;
}
}
if(s1[i] != s2[j])
{
if(s2[j+2]=='*' && (s1[i+1] == s2[j]))
{
int k=0;
while(s1[i+1+k] == s2[j])
{
k++;
j--;
}
continue;
}
break;
}

        if(flag)  puts("yes");
        else puts("no"); 
    }
    
    return 0;