题目链接:http://codeforces.com/contests
A. Bus to Udayland
分析:就是一个手速的贪心题,看懂英文就好了…
/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1005;
int Scan()//读入整数外挂.
{
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
void Out(int a) //输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
char seat[maxn][10];
int n;
int main()
{
#ifndef ONLINE_JUDGE
freopen("coco.txt","r",stdin);
freopen("lala.txt","w",stdout);
#endif
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",seat[i]);
}
bool flag=true;
for(int i=0;i<n;i++)
{
if(seat[i][0]=='O'&&seat[i][1]=='O')
{
flag=false;
seat[i][0]=seat[i][1]='+';
break;
}
if(seat[i][3]=='O'&&seat[i][4]=='O')
{
flag=false;
seat[i][3]=seat[i][4]='+';
break;
}
}
if(flag) printf("NO\n");
else
{
printf("YES\n");
for(int i=0;i<n;i++) printf("%s\n",seat[i]);
}
return 0;
}
B. Chris and Magic Square
分析:这是一道模拟题,看样例就知道,就是跟你一个阵,里面有一个位置是空的(0),然后让你填入一个>0的数,
使得行之和,列之和,对角线之和都相等. 这是一道模拟题,很简单…,按着题意写就行了
/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
int Scan()//读入整数外挂.
{
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
void Out(int a) //输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
int a[505][505];
ll rsum[505];
ll lsum[505];
ll lx;
ll rx;
int n;
ll M;
int si,sj;
void solve()
{
if(n==0) {printf("1\n");return;}
ll c=M-rsum[si];
if(c<=0) {printf("-1\n");return;}
rsum[si]=M;
lsum[sj]+=c;
if((si+sj)==n)rx+=c;
if(si==sj)lx+=c;
if(lx!=rx||lx!=M){printf("-1\n");return;}
for(int i=0;i<n;i++)
{
if(rsum[i]!=M){printf("-1\n");return;}
}
for(int j=0;j<n;j++)
{
if(lsum[j]!=M){printf("-1\n");return;}
}
printf("%I64d\n",c);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("coco.txt","r",stdin);
freopen("lala.txt","w",stdout);
#endif
scanf("%d",&n);
n--;
memset(rsum,0,sizeof(rsum));
memset(lsum,0,sizeof(lsum));
lx=0;
rx=0;
M=(long long)-INF;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j]==0){ si=i;sj=j;}
rsum[i]+=a[i][j];
lsum[j]+=a[i][j];
if(i==j)lx+=a[i][j];
if(i+j==n) rx+=a[i][j];
}
M=max(M,rsum[i]);
}
solve();
return 0;
}
C. Coloring Trees
分析: 这道题扎眼一看就是个dp,我几乎没怎么想,我的代码那时坑在了边界值,忘记处理了,简直天煞,浪费了好多时间也没A掉, dp[i][j][k]:代表我当前所要染色的位置为i,我当前染了第j种颜色,k为连续的个数
这个dp很容易推,所以不多讲.
/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const ll INF=0x3f3f3f3f;
const ll maxn=(ll)100000000000+10;
ll Scan()//读入整数外挂.
{
ll res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
void Out(ll a) //输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
ll n,m,k;
ll dp[105][105][105];//现在选择第i个,上一个选择是C,现在不同的长度是105.
ll p[105][105];
ll tree[105];
int main()
{
scanf("%I64d%I64d%I64d",&n,&m,&k);
for(ll i=0; i<=n; i++)
{
for(ll j=0; j<=m; j++)
{
for(ll K=0; K<=k; K++)
{
if(i==0&&K==0)
{
dp[i][j][K]=0;
continue;
}
dp[i][j][K]=maxn;
}
}
}
for(ll i=1; i<=n; i++)
{
scanf("%I64d",&tree[i]);
}
for(ll i=1; i<=n; i++)
{
for(ll j=1; j<=m; j++)
{
scanf("%I64d",&p[i][j]);
}
}
for(ll i=1; i<=n; i++)
{
for(ll t=1; t<=k; t++)
{
if(tree[i]==0)
{
for(ll se=1; se<=m; se++)
{
if(i!=1)
{
for(ll lse=1; lse<=m; lse++)
{
if(se==lse) dp[i][se][t]=min(dp[i][se][t],p[i][se]+dp[i-1][lse][t]);
else dp[i][se][t]=min(dp[i][se][t],p[i][se]+dp[i-1][lse][t-1]);
}
}
else
{
dp[i][se][t]=min(dp[i][se][t],p[i][se]+dp[i-1][0][t-1]);
}
}
}
else
{
ll se=tree[i];
if(i!=1)
{
for(ll lse=1; lse<=m; lse++)
{
if(se==lse) dp[i][se][t]=min(dp[i][se][t],dp[i-1][lse][t]);
else dp[i][se][t]=min(dp[i][se][t],dp[i-1][lse][t-1]);
}
}
else
{
dp[i][se][t]=min(dp[i][se][t],dp[i-1][0][t-1]);
}
}
}
}
ll ans=maxn;
for(int i=1; i<=m; i++) ans=min(ans,dp[n][i][k]);
if(ans>=maxn)printf("-1\n");
else printf("%I64d\n",ans);
return 0;
}
D. Directed Roads
题解:很水的强连通分量,可以很容易发现对于一个环n,那么破除这个环的总数有(2^N-2)种, 既然时n条边,而且每个点都只有1出度,那么我的想法就是只要破除了环,就可以了,假设有M个点,N个点为环最后答案为2^M *(2^N-2) 用乘法原理解决了 .
ps:如果我没卡上面那题就好了…
/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=2e5+10;
const ll mod=1e9+7;
int Scan()//读入整数外挂.
{
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
void Out(int a) //输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
int V;
vector<int> G[maxn];
vector<int> rG[maxn];
vector<int> vs;
bool used[maxn];
int cmp[maxn];
int cnt_cmp[maxn];
int Sum;
void add_edge(int from ,int to)
{
G[from].push_back(to);
rG[to].push_back(from);
}
void dfs(int v)
{
used[v]=true;
for(int i=0;i<G[v].size();i++)
{
if(!used[G[v][i]]) dfs(G[v][i]);
}
vs.push_back(v);
}
void rdfs(int v,int k)
{
Sum++;
used[v]=true;
cmp[v]=k;
for(int i=0;i<rG[v].size();i++)
{
if(!used[rG[v][i]]) rdfs(rG[v][i],k);
}
}
int scc()
{
memset(used,0,sizeof(used));
vs.clear();
for(int v=0;v<V;v++)
{
if(!used[v]) dfs(v);
}
memset(used,0,sizeof(used));
int k=0;
for(int i=vs.size()-1;i>=0;i--)
{
if(!used[vs[i]])
{
Sum=0;
rdfs(vs[i],k);
cnt_cmp[k++]=Sum;
}
}
return k;
}
ll qmod(ll a,ll n)
{
ll res=1;
while(n)
{
if(n&1)res=(res*a)%mod;
a=(a*a)%mod;
n>>=1;
}
return res%mod;
}
ll qmul(ll a,ll n)
{
ll res=0;
while(n)
{
if(n&1)res=(res+a)%mod;
a=(a+a)%mod;
n>>=1;
}
return res%mod;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("coco.txt","r",stdin);
freopen("lala.txt","w",stdout);
#endif
int to;
scanf("%d",&V);
for(int i=0;i<V;i++)
{
scanf("%d",&to);
to--;
add_edge(i,to);
}
int K=scc();
ll ans=1;
for(int i=0;i<K;i++)
{
if(cnt_cmp[i]>1)
{
ll tmp=(qmod(2,(ll)cnt_cmp[i])-2+mod)%mod;
ans=qmul(ans,tmp);
}
else ans=qmul(ans,2)%mod;
}
printf("%I64d\n",ans);
return 0;
}
E. ZS and The Birthday Paradox
分析:
转载:http://blog.csdn.net/acmore_xiong/article/details/52409248
这个讲得很清楚,我也不懂这个数论的知识,我看了才明白的.
/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const ll mod=1e6+3;
int Scan()//读入整数外挂.
{
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
void Out(int a) //输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
ll n,k;
ll qmod(ll a,ll b,ll MOD)
{
ll ret=1;
while(b)
{
if(b&1)ret=(ret*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ret;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("coco.txt","r",stdin);
freopen("lala.txt","w",stdout);
#endif
scanf("%I64d%I64d",&n,&k);
if(n<64&&(k>((1ll)<<n)))
{
printf("1 1\n");
return 0;
}
ll t=0;
for(ll i=2;i<=(k-1);i<<=1)
{
t+=(k-1)/i;
}
ll gcd=qmod(2,t,mod);
ll x=qmod(2,n,mod);
ll A,B;
A=B=1;
for(ll i=1;i<=(k-1);i++)
{
A=A*(x-i+mod)%mod;
if(!A)break;
}
ll inv=qmod(gcd,mod-2,mod);
A=A*inv%mod;
B=qmod(x,k-1,mod);
B=B*inv%mod;
A=(B-A+mod)%mod;
printf("%I64d %I64d\n",A,B);
return 0;
}