1001 KK的GFriend
本题水题。遍历输入数据给出的字符串。如果出现的I LOVE U各个字符都至少都有m个的话,则满足要求,否则不满足。
之前比赛时,输出描述的字符串和Sample Output不符(Sample Output为正确答案),导致部分同学wrong answer,请见谅。
[cpp] view plain copy print ?
- #include
- #include
- #include
- #include
- using namespace std;
- const int maxn=10001;
- char inp[maxn];
- int num[6];
- int main()
- {
- int cas,n,m;
- scanf("%d",&cas);
- while(cas--)
- {
- memset(num,0,sizeof(num));
- scanf("%d%d",&n,&m);
- for(int i=1; i<=n; i++)
- {
- scanf("%s",&inp);
- for(int i=0; i
- {
- switch(inp[i])
- {
- case 'I':num[0]++;break;
- case 'L':num[1]++;break;
- case 'O':num[2]++;break;
- case 'V':num[3]++;break;
- case 'E':num[4]++;break;
- case 'U':num[5]++;break;
- }
- }
- }
- int res=maxn;
- for(int i=0; i<6; i++)
- res=min(res,num[i]);
- if(res>=m) printf("KK will have a girlfriend!\n");
- else printf("KK can only have gay friend~\n");
-
- }
- return 0;
- }
#include
#include
#include
#include
using namespace std;
const int maxn=10001;
char inp[maxn];
int num[6];
int main()
{
int cas,n,m;
scanf("%d",&cas);
while(cas--)
{
memset(num,0,sizeof(num));
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
scanf("%s",&inp);
for(int i=0; i=m) printf("KK will have a girlfriend!\n");
else printf("KK can only have gay friend~\n");
}
return 0;
}
1002 炮打学弟
这题是一道简单题,主要是要考虑的情况稍多,如果都考虑到了就没有什么了。
需要注意的地方:
1. x2
2. x2=x1时
(1)y=0 输出0.00
(2)y!=0&&vx>0 输出 Xue di so diao can fly
3. x2>x1&&vx=0输出 Xue di so diao can fly
其他情况常规的算一下就可以了。
标准程序:
[cpp] view plain copy print ?
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- using namespace std;
- #define mmax 100000+100
- int main(){
- int x1,x2,y,vx;
- double vy,g=9.8;
- int t;
- cin>>t;
-
-
- while(t--){
- cin>>x1>>x2>>y>>vx;
- if(x1>x2){
- cout<<"Xue di so diao can fly"<
- continue;
- }
- if(x1==x2){
- if(y==0){
- printf("%.2f\n",0.00);
- continue;
- }
- else if(vx>0) cout<<"Xue di so diao can fly"<
- else{
- double t=sqrt(2*y/g);
- printf("%.2f\n",g*t);
- }
- continue;
- }
- else{
- if(vx==0){
- cout<<"Xue di so diao can fly"<
- continue;
- }
- else{
- double t=(x2-x1)*1.0/vx;
- vy=(0.5*g*t*t+y)/t;
- printf("%.2f\n",vy);
- }
- }
- }
- }
#include
#include
#include
#include
#include
#include
#include
#include
1003 区间平均值
这题是水题,直接暴力求平均值即可。
1004 饿了么
这题是水题,直接排个序就好了,1000的数据量,用冒泡排序都可以。
1005 分辨机器人
m<=15 2^15==32768 所以可以直接暴力解决。但是由于开始数据出问题了,导致很多同学wa了,实在抱歉,想知道自己算法是否OK的同学可以到赛后(http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1005&cid=25698&problem=Problem%20%20E)提交。
标准程序:
[cpp] view plain copy print ?
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define pb push_back
- #define lson l,m,rt<<1
- #define rson m+1,r,rt<<1|1
- typedef long long LL;
- using namespace std;
- int s[105][20];
- int T,n,m,ans;
- int B[20];
- string ko;
- mapint>M;
- void dfs(int *B,int num)
- {
- if(num==m)
- {
- M.clear();
- for(int i=1;i<=n;i++)
- {
- ko = "";
- for(int j=1;j<=m;j++)
- if(B[j]==1) ko += (s[i][j]+'0');
- if(M[ko]) return ;
- else M[ko] = 1;
- }
- int flag = 0;
- for(int i=1;i<=m;i++) flag+=B[i];
- if(ans>flag)
- ans = flag;
- }
- else
- {
- B[num+1] = 0;
- dfs(B,num+1);
- B[num+1] = 1;
- dfs(B,num+1);
- }
- }
- void solve()
- {
- ans = m;
- B[0] = 0;
- dfs(B,0);
- printf("%d\n",ans);
- }
- int main()
- {
- scanf("%d",&T);
- while(T--)
- {
- memset(B,0,sizeof(B));
- scanf("%d%d",&n,&m);
- for(int i=1; i<=n; i++)
- for(int j=1; j<=m; j++)
- {
- scanf("%d",&s[i][j]);
- }
- solve();
- }
- return 0;
- }
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
1006 佳米的问题
这是一个想法题,首先我们需要找出最大的LCM(x,y).由于x+y==m&& x>=1 && y>=1 ,有一个很简单的数学依据,加入我们只是找(x*y)最大,那肯定( m/2*(m-m/2) )最大,因为这就是一个开口向下的二次函数曲线,而顶点就是(m/2)或者(m-m/2),但是我们要找的是x与y的最小公倍数,所以只需要从m/2开始向下枚举x,找到gcd(x,m-x)==1,此时LCM(x,y)最大。
然后就是如何用LCM(x,y)去填充数组使得最小的元素最大的问题了,那么这个其实有一个很简单的方法,直接二分答案即可。
标准程序:
[cpp] view plain copy print ?
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define pb push_back
- #define lson l,m,rt<<1
- #define rson m+1,r,rt<<1|1
- typedef long long LL;
- using namespace std;
- LL gcd(LL a,LL b)
- {
- return a==0?b:gcd(b%a,a);
- }
- const int maxn = 100010;
- LL s[maxn];
- LL T,n,num,m;
- bool solve(LL mid,LL num)
- {
- LL ok = num;
- for(int i=1;i<=n;i++)
- {
- if(s[i] < mid){
- ok -= abs( mid - s[i] );
- }
- if(ok<0) break;
- }
- return ok>=0;
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
- freopen("out2.txt","w",stdout);
- #endif ///ONLINE_JUDGE
- scanf("%I64d",&T);
- while(T--){
- scanf("%I64d",&n);
- for(int i=1;i<=n;i++)
- {
- scanf("%I64d",&s[i]);
- }
- scanf("%I64d",&m);
- for(LL i=m/2;i>=1;i--)
- {
- if(gcd(i,m-i)==1)
- {
- num=i*(m-i);
- break;
- }
- }
- LL l=-1*1e9,r = 1ll*1e16,mid,ans=-1*1e9;
- while(l<=r)
- {
- mid = (l+r)/2;
- if(solve(mid,num)){
- ans = max(ans,mid);
- l = mid + 1;
- }
- else r = mid - 1;
- }
- printf("%I64d\n",ans);
- }
- return 0;
- }
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
1007 Crisis
图论。本题可谓是排在难题位置的简单题。描述偏多,但是只要学习过最大流算法的同学应该都可以做出来。
N件武器,每件都可以选择特定的几个目标进行攻击。但是每件武器只允许攻击一次并只能造成1点伤害。因此,我们构建网络,将n件武器每件当作一个点,与源点相连,形成的边容量为1。再将m个目标当作n个点,若某一武器能够攻击到敌人,则将它们两个点相连,边容量为1。
又由于每个敌人的护盾有限。而被摧毁的战舰无法再被攻击,因此,将m个敌人分别与汇点相连,边容量为该敌人的护盾值。
至此,建模完毕。接下来只需要套用最大流算法,即可计算出最大攻击输出。
标准程序:
[cpp] view plain copy print ?
- #include
- #include
- #include
- #include
- #include
- #include
- #define INF 0x7fffffff
- using namespace std;
- const int maxn=1010;
- class Edge
- {
- public :
- int from,to,cap,flow;
- Edge(int fr,int t,int c,int fl)
- {
- from=fr;
- to=t;
- cap=c;
- flow=fl;
- };
- };
-
- class Dinic
- {
- private:
- int s,t,c,m,n;
- vectoredges;
- vector<int>G[maxn];
- bool vis[maxn];
- int dist[maxn];
- int cur[maxn];
- public:
- void AddEdge(int from,int to,int cap)
- {
- Edge e(from,to,cap,0);
- edges.push_back(e);
- e.from=to;
- e.to=from;
- e.cap=0;
- edges.push_back(e);
- c=edges.size();
- G[from].push_back(c-2);
- G[to].push_back(c-1);
- }
- bool BFS()
- {
- queue<int>Q;
- memset(vis,0,sizeof(vis));
- Q.push(s);
- dist[s]=0;
- vis[s]=1;
- while(!Q.empty())
- {
- int x=Q.front();
- Q.pop();
- for(int i=0; i
- {
- Edge& e=edges[G[x][i]];
- if(!vis[e.to]&&e.cap>e.flow)
- {
- vis[e.to]=1;
- dist[e.to]=dist[x]+1;
- Q.push(e.to);
- }
- }
- }
- return vis[t];
- }
- int DFS(int x,int a)
- {
- if(x==t||a==0)return a;
- int flow=0,f;
- for(int& i=cur[x]; i
- {
- Edge& e=edges[G[x][i]];
- if(dist[x]+1==dist[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
- {
- e.flow+=f;
- edges[G[x][i]^1].flow-=f;
- flow+=f;
- a-=f;
- if(a==0)break;
- }
- }
- return flow;
- }
- int Maxflow(int s,int t)
- {
- this->s=s;
- this->t=t;
- int flow=0;
- while(BFS())
- {
- memset(cur,0,sizeof(cur));
- flow+=DFS(s,INF);
- }
- return flow;
- }
- void init()
- {
- edges.clear();
- for(int i=0; i
- {
- G[i].clear();
- dist[i]=0;
- }
- }
- } Do;
- int main()
- {
- int n,m,k,hp,t;
- cin>>t;
- while(t--)
- {
- cin>>n>>m;
- Do.init();
- for(int i=1; i<=n; i++)
- {
- Do.AddEdge(0,i,1);
- cin>>k;
- int tar;
- for(int j=1; j<=k; j++)
- {
- cin>>tar;
- Do.AddEdge(i,n+tar,1);
- }
- }
- for(int i=1; i<=m; i++)
- {
- cin>>hp;
- Do.AddEdge(n+i,n+m+1,hp);
- }
- cout<
-
- }
- return 0;
- }
#include
#include
#include
#include
#include
#include
#define INF 0x7fffffff
using namespace std;
const int maxn=1010;
class Edge
{
public :
int from,to,cap,flow;
Edge(int fr,int t,int c,int fl)
{
from=fr;
to=t;
cap=c;
flow=fl;
};
};
class Dinic
{
private:
int s,t,c,m,n;
vectoredges;
vectorG[maxn];
bool vis[maxn];
int dist[maxn];
int cur[maxn];
public:
void AddEdge(int from,int to,int cap)
{
Edge e(from,to,cap,0);
edges.push_back(e);
e.from=to;
e.to=from;
e.cap=0;
edges.push_back(e);
c=edges.size();
G[from].push_back(c-2);
G[to].push_back(c-1);
}
bool BFS()
{
queueQ;
memset(vis,0,sizeof(vis));
Q.push(s);
dist[s]=0;
vis[s]=1;
while(!Q.empty())
{
int x=Q.front();
Q.pop();
for(int i=0; ie.flow)
{
vis[e.to]=1;
dist[e.to]=dist[x]+1;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x,int a)
{
if(x==t||a==0)return a;
int flow=0,f;
for(int& i=cur[x]; i0)
{
e.flow+=f;
edges[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
return flow;
}
int Maxflow(int s,int t)
{
this->s=s;
this->t=t;
int flow=0;
while(BFS())
{
memset(cur,0,sizeof(cur));
flow+=DFS(s,INF);
}
return flow;
}
void init()
{
edges.clear();
for(int i=0; i>t;
while(t--)
{
cin>>n>>m;
Do.init();
for(int i=1; i<=n; i++)
{
Do.AddEdge(0,i,1);
cin>>k;
int tar;
for(int j=1; j<=k; j++)
{
cin>>tar;
Do.AddEdge(i,n+tar,1);
}
}
for(int i=1; i<=m; i++)
{
cin>>hp;
Do.AddEdge(n+i,n+m+1,hp);
}
cout<
1008 KiKi的难题
这题是一个简单的三维的dp。
Intdp[110][110][110];
dp[i][j][k] 表示第i个岛屿到第j个岛屿没有挖且使用魔法棒剩余次数为k 所能获得大最大价值
[cpp] view plain copy print ?
- for(int i=n-1; i>=1; i--)
- for(int j=1;j+i-1<=n; j++)
- for(int k=0; k<=m; k++)
- {
- int add=j+i-1;
- if(j!=1)
- {
- dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k]+p[j-1]);
- dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k+1]+(m-k)*p[j-1]);
- }
- if(add!=n)
- {
- dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k]+p[add+1]);
- dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k+1]+(m-k)*p[add+1]);
- }
- }
for(int i=n-1; i>=1; i--)//枚举剩余岛屿的个数
for(int j=1;j+i-1<=n; j++)//枚举最左边的岛屿位置
for(int k=0; k<=m; k++)//枚举魔法棒可使用的次数
{
int add=j+i-1;
if(j!=1)
{
dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k]+p[j-1]);
dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k+1]+(m-k)*p[j-1]);
}
if(add!=n)
{
dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k]+p[add+1]);
dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k+1]+(m-k)*p[add+1]);
}
}
最后输出最大值就可以了。
标准程序:
[cpp] view plain copy print ?
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- using namespace std;
- int dp[110][110][110];
- int main(){
- int t;cin>>t;
- int n,m,p[110];
- while(t--){
- cin>>n>>m;
- for(int i=1;i<=n;i++) cin>>p[i];
- memset(dp,0,sizeof(dp));
- for(int i=n-1; i>=1; i--)
- {
- for(int j=1; j+i-1<=n; j++)
- for(int k=0; k<=m; k++)
- {
- int add=j+i-1;
- if(j!=1)
- {
- dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k]+p[j-1]);
- dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k+1]+(m-k)*p[j-1]);
- }
- if(add!=n)
- {
- dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k]+p[add+1]);
- dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k+1]+(m-k)*p[add+1]);
- }
- }
- }
- int mmax=0;
- if(m==0) cout<
- else{
- for(int i=1;i<=n;i++) mmax=max(mmax,dp[i][i][1]+p[i]*m);
- cout<
- }
- }
- return 0;
- }
#include
#include
#include
#include
#include
#include
#include
#include
#include
以上即是本次比赛的全部解题报告以及部分标准程序代码,感谢大家对我校比赛的支持!