2015 UESTC Winter Training #9

传送门

这场比赛是2010东京区域赛的题目,只做了几题简单的题目

Aizu 1305 Membership Management

题意:给你几个部门的人,一个部门可能包含于另一个部门之下

问:第一个部门有多少人

用map给每个部门编号,然后set数组存每个部门人名,然后用dfs搜索答案

<span style="font-size:18px;">//      whn6325689
//		Mr.Phoebe
//		http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")


using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1;
    char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

map<string,int> g;
set<string> ss[101],ans;
int n,vis[101];

void init(int n)
{
	g.clear();ans.clear();
	for(int i=1;i<=n;i++)
		ss[i].clear();
	CLR(vis,0);
}

void dfs(int i)
{
	vis[i]=1;
	for(set<string>::iterator it=ss[i].begin();it!=ss[i].end();it++)
	{
		if(g.count(*it))
		{
			if(!vis[g[*it]])
				dfs(g[*it]);
		}
		else
			ans.insert(*it);
	}
}

int main()
{
//	freopen("data.txt","r",stdin);
	string str;
	while(read(n)&&n)
	{	
		init(n);
		for(int i=1;i<=n;i++)
		{
			cin>>str;str[str.length()-1]=','; 
			int pos=str.find(':');
			string temp=str.substr(0,pos);
			g[temp]=i;//cout<<temp<<endl;
			while(1)
			{
                str=str.substr(pos+1);
                pos=str.find(',');
                if(pos==-1)
					break;
				temp=str.substr(0,pos);
                ss[i].insert(temp);
            }
		}
		dfs(1);
		write(ans.size()),putchar('\n');
	}
	return 0;
}</span>

Aizu 1306 Balloon Collecting

题意:n气球从上往下掉,给你掉落的位置和掉落的时间,给你一个初始位置在0的车,去接气球,最多可以装3个气球,就必须返回0点去放气球,单位速度为气球数 k+1

问:如果可以将气球全部接住,求最短距离;如果不能将气球全部接住,求第一个接不住的气球编号

简单dp,dp[i][j]表示第i个气球的时候,车上有j个气球时候的最短距离

这个转移很好搞定,见代码

<span style="font-size:18px;">//      whn6325689
//		Mr.Phoebe
//		http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")


using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1;
    char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

struct Node
{
	int t,p;
	Node(const int& p=0,const int& t=0):t(t),p(p){}
}b[44];
int dp[44][4];

int main()
{
//	freopen("data.txt","r",stdin);
	int n;
	while(read(n)&&n)
	{
		CLR(dp,INF);
		dp[0][0]=0;
		bool flag=0;
		for(int i=1;i<=n;i++)
		{
			read(b[i].p),read(b[i].t);
			if(flag)	continue;
			int dis=abs(b[i].p-b[i-1].p);
			int tim=b[i].t-b[i-1].t;
			for(int j=1;j<=3;j++)
				if(dis*j<=tim)
					dp[i][j]=min(dp[i][j],dp[i-1][j-1]+dis);
			for(int j=1;j<=3;j++)
				if(b[i].p+b[i-1].p*(j+1)<=tim)
					dp[i][1]=min(dp[i][1],dp[i-1][j]+b[i-1].p+b[i].p);
			int minn=INF;
			for(int j=1;j<=3;j++)
            {
               minn=min(minn,dp[i][j]);
//               cout<<dp[i][j]<<" ";
            }
//            cout<<endl;
			if(minn==INF)
			{
				flag=1;
				printf("NG %d\n",i);
			}
		}
		if(!flag)
		{
			int ans=INF;
			for(int i=1;i<=3;i++)
				ans=min(ans,dp[n][i]+b[n].p);
			printf("OK %d\n",ans);
		}
	}
	return 0;
}</span>

Aizu 1308 Awkward Lights

题意:给你一个n*m的01矩阵,然后开关灯,给你一个d,翻转开关的时候,以开关为中心的曼哈顿距离为d的开关全部翻转

问:可否全部关灯完毕

高斯消元解异或方程组,如果不可解则说明不行

<span style="font-size:18px;">//      whn6325689
//		Mr.Phoebe
//		http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")


using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1;
    char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

const int MAXN=26*26;

int b[MAXN][MAXN],ans[MAXN];
int a[MAXN][MAXN];

bool Guass(int n)  
{  
    int i,j,row,col;  
    for(row=0,col=0;row<n && col<n;row++,col++)  
    {    
        for(i=row;i<n;i++)
            if(a[i][col]!=0)  
                break;  
        for(j=col;j<=n && i!=n && i!=row;j++)
            swap(a[row][j],a[i][j]);
		if(!a[row][col])
		{
			row--;continue;
		} 
        for(i=row+1;i<n;i++)  
            if(a[i][col])  
                for(j=col+1;j<=n;j++)  
                    a[i][j]=a[row][j]^a[i][j];  
    }  
    for(i=row;i<n;i++)  
        if(a[i][n])
			return 0;
	return 1; 
} 



int main()
{
//	freopen("data.txt","r",stdin);
	int n,m,d;
	while(read(m)&&read(n)&&read(d)&&(n+m+d))
	{
		CLR(a,0);
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				read(b[i][j]);
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
			{
				a[i*m+j][n*m]=b[i][j];
				a[i*m+j][i*m+j]=1;
				for(int x=0;x<n;x++)
					for(int y=0;y<m;y++)
						if(abs(x-i)+abs(y-j)==d)
							a[i*m+j][x*m+y]=1;
			}
		if(Guass(n*m))
			puts("1");
		else
			puts("0");
	}
	return 0;
}</span>

Aizu 1310 Find the Multiples

题意:给你一个a[0]~a[n-1]的数组,二元组(i,j)表示a[i]~a[j]的一个数,可以认为是一个十进制的数

问:有多少给(i,j)截取的数,是素数Q的倍数

暴搜会TLE

首先,我们考虑A=(i,j)和B=(I,j)其中I<i,那么数字B-A,则会得到一个有多个后缀零的数,那么如果,B,A mod Q的余数相同,则相减之后,B-A再除以10的幂,就为(I,i)就可以整除Q

那么当10不能整除Q的时候,就可以直接用B-A来代替二元组(I,i)来计算,从而变成一维的解法

那么当Q是2或者5的时候,10可以整除Q,那么就要单独计算

<span style="font-size:18px;">//      whn6325689
//		Mr.Phoebe
//		http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")


using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1;
    char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

const int MAXN=100010;
ll n,s,p,w;

map<ll,ll> ma;
ll a[MAXN];

int main()
{
//	freopen("data.txt","r",stdin);
	while(read(n)&&read(s)&&read(w)&&read(p)&&(n+s+p+w))
	{
		ma.clear();
		int g=s,ans=0,num=0;
	    for(int i=0; i<n; i++) {
	        a[i] = (g/7) % 10;
	        if( g%2 == 0 ) { g = (g/2); }
	        else           { g = (g/2) ^ w; }
	    }
	    if(p==2 || p==5)
	    {
    		for(int i=0;i<n;i++)
    		{
		    	if(a[i])	num++;
	    		if(a[i]%p==0)	ans+=num;
		    }
    	}
    	else
    	{
    		int t=1;
	    	for(int i=n-1;i>=0;i--)
	    	{
	    		num=(a[i]*t+num)%p;
	    		if(a[i])	ans+=ma[num];
	    		ma[num]++;
	    		if(a[i] && num==0)	ans++;
	    		t=(t*10)%p;
	    	}
	    }
	    write(ans),putchar('\n');
    	continue;
	}
	
}</span>

Aizu 1311 Test Case Tweaking

题意:给你一个图,一个数C

问:最少修改多少条边使得图的最短路等于C,保证原先的最短路大于等于C

图上DP,dp[i][j]表示在i节点的时候,修改j次之后最短的距离

转移当这次不修改的时候,则在同一个j下面转移 dp[i][j] = min( dp[u][j] + g[u][i] )

当修改这条边的时候,则直接将其修改成0,dp[i][j] = min( dp[u][j-1] )

最后到达n点,则如果最短距离小于C,则认为中间有一些改成0的减太多了,稍微加一些就可以达到C,则满足题意

<span style="font-size:18px;">//      whn6325689
//		Mr.Phoebe
//		http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")


using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1;
    char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

const int MAXN=111;

int g[MAXN][MAXN],dp[MAXN][MAXN];
bool vis[MAXN];
int n,m,c;

void spfa()
{
    CLR(vis,0);
    queue<int> q;
    q.push(1);
    dp[1][0]=0;
    vis[1]=true;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=1; i<=n; i++)
        {
            if(~g[u][i])
            {
                for(int j=0; j<=n; j++)
                {
                    if(dp[u][j]+g[u][i]<dp[i][j])
                    {
                        dp[i][j]=dp[u][j]+g[u][i];
                        if(!vis[i])
                        {
                            q.push(i);
                            vis[i]=1;
                        }
                    }
                    if(j && dp[u][j-1]<dp[i][j])
                    {
                        dp[i][j]=dp[u][j-1];
                        if(!vis[i])
                        {
                            q.push(i);
                            vis[i]=1;
                        }
                    }
                }
            }
        }
    }
}
int main()
{
//    freopen("data.txt","r",stdin);
    while(read(n)&&read(m)&&read(c)&&(n+m+c))
    {
        CLR(g,-1);
        CLR(dp,INF);
        for(int i=0,u,v,dis; i<m; i++)
        {
            read(u),read(v),read(dis);
            g[u][v]=dis;
        }
        spfa();
        for(int i=0; i<=n; i++)
            if(dp[n][i]<=c)
            {
                printf("%d\n",i);
                break;
            }
    }
    return 0;
}</span>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值