先发Div2的吧,Div1的要看能搞定多少……(一般不全搞出来是不会写题解的……)
【A. Dragons】
http://www.codeforces.com/contest/230/problem/A
题目大意:有个人打怪兽,自己和怪兽都有一个属性,属性高的能战胜低的,打败一个怪兽能获得额外属性。问能否全胜通关。
从小到大打就是了……没什么意思……
#include <iostream>
#include <algorithm>
using namespace std;
int s,n;
struct REC{int x,y;}a[1010];
bool cmp(REC a,REC b){
return a.x<b.x;
}
int main(){
cin>>s>>n;
for(int i=1;i<=n;i++)
cin>>a[i].x>>a[i].y;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
if(s<=a[i].x){
cout<<"NO"<<endl;
return 0;
}
s+=a[i].y;
}
cout<<"YES"<<endl;
}
【B. T-primes】
http://www.codeforces.com/contest/230/problem/B
题目大意:给定一堆数,判断他们每个是不是T-prime,T-prime数定义为该数有且仅有三个质因子。
任何一个数都有1和它本身俩质因子。还剩一个……是啥呢?只有sqrt(n)。因为如果不是它的话,必然会产生偶数个质因子。
比较坑人,也没什么意思……
#include <iostream>
#include <cmath>
#define sqr(x) ((x)*(x))
using namespace std;
bool composite[1000010];
int n;
long long x;
int main(){
composite[1]=true;
for(int i=2;i<=1000000;i++)
if(!composite[i]){
for(int j=2;i*j<=1000000;j++)
composite[i*j]=true;
}
cin>>n;
while(n--){
cin>>x;
if(sqr((long long)sqrt(x))!=x) cout<<"NO"<<endl;
else if(composite[(int)sqrt(x)]) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
}
【C. Shifts】
http://www.codeforces.com/contest/230/problem/C
做div1的时候这个题挂了,很囧……
题目大意:给一个01矩阵,行可以转(密码锁那样),问最少转几次出现一列全是1.
mov[i][j]表示使第i行第j列出现1的最少移动次数。循环的数组显然要拆分一下,然后正着倒着各一边dp,最后枚举列统计一下就ok了……
#include <iostream>
#include <cstring>
using namespace std;
template<class T>inline void gmin(T &a,T b){if(a>b)a=b;}
char s[10010];
int n,m,ans=2147483647,mov[110][10010],tmp;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=0;j<m;j++) mov[i][j]=1000000;
for(int i=1;i<=n;i++){
cin>>s;
for(int j=0;j<m;j++)
if(s[j]=='1') mov[i][j]=0;
for(int j=0;j<m<<1;j++)
gmin(mov[i][j%m],mov[i][(j-1+m)%m]+1);
for(int j=(m<<1)-1;j>=0;j--)
gmin(mov[i][j%m],mov[i][(j+1)%m]+1);
}
for(int j=0;j<m;j++){
tmp=0;
for(int i=1;i<=n;i++)
tmp+=mov[i][j];
gmin(ans,tmp);
}
cout<<(ans>=1000000?-1:ans)<<endl;
}
【D. Planets】
http://www.codeforces.com/contest/230/problem/D
题目大意:无向图从1走到n,某些特殊时间某些特殊点不能出发,问最短时间。
大概算法就是最短路就行(比如SPFA),复杂度瓶颈在于如何知道某一点某一时刻能不能走,可以对于每个点建一个查找树,就过了。C++用map或者set都行。
#include <iostream>
#include <cstring>
#include <queue>
#include <map>
#define mn 100010
#define mm 200010
using namespace std;
map<int,bool> bst[mn];
queue<int> q;
int n,m,a,b,c,dist[mn];
bool vis[mn];
struct EDGE{
int pnt,dist;
EDGE *pre;
EDGE(){}
EDGE(int _pnt,int _dist,EDGE *_pre):pnt(_pnt),pre(_pre),dist(_dist){}
}Edge[mm],*SP=Edge,*edge[mn];
inline void addedge(int a,int b,int c){
edge[a]=new(++SP)EDGE(b,c,edge[a]);
edge[b]=new(++SP)EDGE(a,c,edge[b]);
}
int main(){
cin>>n>>m;
while(m--){
cin>>a>>b>>c;
addedge(a,b,c);
}
for(int i=1;i<=n;i++){
cin>>a;
while(a--){
cin>>b;
bst[i][b]=true;
}
}
memset(dist,0x7f,sizeof(dist));
dist[1]=0;
q.push(1);
while(!q.empty()){
int i=q.front();q.pop();
vis[i]=false;
int cur_time=dist[i];
while(bst[i][cur_time]) cur_time++;
for(EDGE *j=edge[i];j;j=j->pre)
if(j->dist+cur_time<dist[j->pnt]){
dist[j->pnt]=cur_time+j->dist;
if(!vis[j->pnt]){
vis[j->pnt]=true;
q.push(j->pnt);
}
}
}
cout<<(dist[n]==dist[0]?-1:dist[n])<<endl;
}
【E. Triangles】
http://www.codeforces.com/contest/230/problem/E
题目大意:一个完全图,拆成两部分,问这两部分一共有多少三角形。
完全图中共有C(n,3)个三角形,对于某个点x,如果有deg[x]个点与x相连,那么剩下(n-x-1)个点就不与x相连了,于是就减少了deg[x]*(n-deg[x]-1)个包含x的三角形(乘法原理)。最后处理一下重复统计。
#include <cstdio>
int m,a,b,deg[1000010];
long long n,tri;
int main(){
scanf("%I64d%d",&n,&m);
while(m--){
scanf("%d%d",&a,&b);
deg[a]++,deg[b]++;
}
for(int i=1;i<=n;i++)
tri+=(long long)deg[i]*(n-deg[i]-1);
tri>>=1;
printf("%I64d\n",n*(n-1)*(n-2)/6-tri);
}
Div1努力搞中……