河南省多校联萌(一)

A没做

 

B地址 http://codeforces.com/problemset/problem/754/B

哎,一个可以说是普通的水题,却卡了一段时间WA数次由于考虑不周全和一些sb错误。

先是把题目中的'x'看做了'X',一口老血,后来懒得改上面(太多X了),就想着直接把x换成X,结果....在未修改完之后就进行判定导致WA,还少写了两个情况。

哎自己还是太粗心,代码能力有待提高啊= =

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<set>
 6 #include<sstream>
 7 using namespace std;
 8 #define LOCAL
 9 #define LL long long
10 #define ql(a) memset(a,0,sizeof(a))
11 char e[15][15];
12 bool ok(int x,int y)
13 {//if(x==2&&y==4)cout<<e[x][y-1]<<" "<<e[x][y-2]<<endl;
14         if(e[x][y-1]=='X'&&e[x][y-2]=='X') {return 1;}  //每个三连有可能竖着,横着,主对角线,副对角线,这四种情况中待填充的位置又分为三个
15         if(e[x][y+1]=='X'&&e[x][y+2]=='X') {return 1;}   //所以一共12种情况,当然嫌麻烦也可以用for找。
16         if(e[x-1][y]=='X'&&e[x-2][y]=='X') {return 1;}
17         if(e[x+1][y]=='X'&&e[x+2][y]=='X') {return 1;}
18         if(e[x][y-1]=='X'&&e[x][y+1]=='X') {return 1;}
19         if(e[x-1][y]=='X'&&e[x+1][y]=='X') {return 1;}
20         if(e[x+1][y-1]=='X'&&e[x+2][y-2]=='X') {return 1;}
21         if(e[x-1][y+1]=='X'&&e[x-2][y+2]=='X') {return 1;}
22         if(e[x+1][y-1]=='X'&&e[x-1][y+1]=='X') {return 1;}
23         if(e[x-1][y-1]=='X'&&e[x+1][y+1]=='X') {return 1;}
24         if(e[x+1][y+1]=='X'&&e[x+2][y+2]=='X') return 1;
25         if(e[x-1][y-1]=='X'&&e[x-2][y-2]=='X') return 1;
26 return 0;
27 }
28 int main()
29 {
30 
31     int i,j,k;
32         for(i=2;i<=5;++i)
33             for(j=2;j<=5;++j) {
34                     cin>>e[i][j];
35                     if(e[i][j]=='x') e[i][j]='X';
36             }
37             bool ook=0;
38         for(i=2;i<=5;++i)
39             for(j=2;j<=5;++j){
40         if(e[i][j]=='.'&&ok(i,j)) {ook=1;break;}
41             }
42         ook?puts("YES"):puts("NO");
43     return 0;
44 }

 

 

C 不想说啥,多个字母有可能通过字符相连,妥善处理

 

D没开

 

E http://www.lydsy.com/JudgeOnline/problem.php?id=1083

贪心,n个点最少通过n-1条线连接,题目要使得最大权值的边的值最小化,

我们对所有边按照权值升序排列,每次利用并查集将边对应的两个点合并,当有效连接边达到n-1时此时当前边的权值就是答案。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<set>
 6 using namespace std;
 7 #define LOCAL
 8 #define LL long long
 9 #define ql(a) memset(a,0,sizeof(a))
10 int f[333];
11 int getf(int v){return f[v]==v?f[v]:f[v]=getf(f[v]);}
12 struct node
13 {
14     int u,v,w;
15     bool operator<(const node &c)const{
16     return w<c.w;
17     }
18 }P[150000];
19 int main()
20 {
21     int n,m,i,j,k;
22     while(cin>>n>>m){
23         for(i=0;i<=n;++i) f[i]=i;
24         for(i=1;i<=m;++i){
25             cin>>P[i].u>>P[i].v>>P[i].w;
26         }
27         sort(P+1,P+1+m);
28         int s=0;
29         for(i=1;i<=m;++i){
30             int u=P[i].u,v=P[i].v;
31             int fu=getf(u),fv=getf(v);
32             if(fu!=fv){
33                 f[f[v]]=fu;
34                 s++;
35             }
36             if(s==n-1){cout<<s<<" "<<P[i].w<<endl;break;}
37         }
38     }
39     return 0;
40 }

 

 

F.

 

有趣的一道状压DP,有趣当然是因为 47啦! 当年可是看了之后大爱这个光头大佬得吖! 可惜第二部换猪脚了= =

我们用dp[S]表示达到S状态(0表示未杀,1表示已杀)所花费的最小次数,初始化dp[0]=0  dp[other]=inf;

对于S,无论再杀死哪一个人,对应的状态都只会在S的后面,换句话说S更新别人的他自己肯定不会再被更新-。-

利用我为人人的方法更新后面状态的值,  对于S,遍历有0的位置更新将此为变为1后的状态,注意处理好hurt数组和向上取整。

如果用人人为我递推的话由于状态的不同写起来递推式很麻烦,不推荐。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 #define inf 0x3f3f3f3f
 7 int dp[1<<15],N,K=0;
 8 int hp[25],e[20][20];
 9 int hurt[25];
10 void solve()
11 {
12     memset(dp,inf,sizeof(dp)); dp[0]=0;
13     for(int k=0;k<(1<<N);++k)
14     {
15        for(int i=0;i<N;++i)  hurt[i]=1;
16        for(int i=0;i<N;++i)
17        {
18         if(k&(1<<i))
19             for(int j=0;j<N;++j) hurt[j]=max(hurt[j],e[i][j]);
20        }
21        for(int i=0;i<N;++i)
22        {
23            if(!(k&(1<<i))){
24             int tar=(k|(1<<i));
25             dp[tar]=min(dp[tar],(int)(dp[k]+ceil(1.0*hp[i]/hurt[i])));
26            }
27        }
28     }
29   printf("Case %d: %d\n",++K,dp[(1<<N)-1]);
30 }
31 int main()
32 {
33     int t,i,j;
34     char c;
35     cin>>t;
36     while(t--){
37         cin>>N;
38         for(i=0;i<N;++i) cin>>hp[i];
39         for(i=0;i<N;++i)
40             for(j=0;j<N;++j) cin>>c,e[i][j]=c-'0';
41         solve();
42     }
43     return 0;
44 }

 

 

G.没写

 

H.sb了中间爆了long long一直没想到,该测几组大数据的

http://codeforces.com/problemset/problem/758/D

也是贪心(也可以dp?但贪心就很easy了)

要使得这个数最小,就要让最小位的数越大越好,注意这个数不能有前导零。

从后之前找数,尽可能接近n但不可>=n,每遇到一个临界点就   ans+=num*pow(n,p++)  //p代表当前处理到的位

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 #define inf 0x3f3f3f3f
 8 #define LL long long
 9 LL qpow(LL a,LL b)
10 {   LL r=1;
11     while(b){
12       if(b&1) r*=a;
13       b>>=1;
14       a*=a;
15     }
16     return r;
17 }
18 LL num(LL i,LL j,char a[])
19 {
20     LL s=0;
21     for(LL k=i;k<=j;++k) s=s*10+(LL)(a[k]-'0');
22     if(s<0) return 999999999;  // 爆了long long 坑定大于n,返回一个极大值即可,表示这个数超n了
23     return s;
24 }
25 int main()
26 {
27     LL n,i,j,l,p=0;
28     char k[100];
29     LL ans=0;
30     cin>>n>>k;
31     l=strlen(k);
32     for(i=l-1;i>=0;--i){bool ok=0;
33             for(j=0;j<i;++j)
34             {
35                 if(k[j]=='0') continue;
36                 LL t=num(j,i,k);
37                 if(t<n) {ans+=t*qpow(n,p++);i=j;ok=1;break;}
38             }
39             if(!ok) ans+=(LL)(k[i]-'0')*qpow(n,p++);
40 
41     }
42     cout<<ans<<endl;
43     return 0;
44 }

 

转载于:https://www.cnblogs.com/zzqc/p/7252508.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值