传送门
这场比赛是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>