先上连接http://codeforces.com/contest/1118;
A Water Buying
题意为叫你n升水,有两升一桶,一升一桶,分别给出价钱,叫你用最少钱的买水,题目不难,比较两种水,哪一种划算,最后如果剩了一升水,只能用一升一桶的,直接上代码
///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
const int N=400010;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
ll t;cin>>t;
ll n,a,b;
while(t--)
{
cin>>n>>a>>b;
if(a<=b/2)
{
cout<<n*a<<endl;
}
else
{
cout<<b*(n/2)+a*(n%2)<<endl;
}
}
return 0;
}
B Tanya and Candies
题意:给出n个数,你可以在里面去除一个,然后使奇数项的和等于偶数项,问这样的数一共有几个,直接处理前缀奇数偶数项和就可以了,然后枚举每一个数就可以了。
///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
const int N=200010;
int a[200010];
int l[N],r[N],sl[N],sr[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(i%2)
l[i]=a[i];
else
r[i]=a[i];
sl[i]=sl[i-1]+l[i];
sr[i]=sr[i-1]+r[i];
}
int ans=0;
int tmp1,tmp2;
for(int i=1;i<=n;i++)
{
tmp1=sl[i-1],tmp2=sr[i-1];
tmp2+=sl[n]-sl[i];
tmp1+=sr[n]-sr[i];
if(tmp1==tmp2)
ans++;
}
cout<<ans<<endl;
return 0;
}
C Palindromic Matrix
题意:给你n*n个数,问你是否能构成一个上下左右对称的矩阵,这道题模拟,偶数还好弄,奇数先做到出现4次或者4次多的数,记录下来,然后从下面的数中找出,还剩下2次及以上的数,最后一次的数,放的时候就放一个角,其他也如此放,正着放一次,反着放一次。
///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
const int N = 25;
int a[N*N];
int ans[N][N];
map<int, int>mp;
int main()
{
memset(ans, 0, sizeof(ans));
int n;
cin >> n;
int l = 1, r = 1;
int cont = 0;
for (int i = 1; i <= n*n; i++)
{
cin >> a[i];
mp[a[i]]++;
if (mp[a[i]] == 4 && cont != (n / 2)*(n / 2))
{
mp[a[i]] = 0;
ans[l][r++] = a[i];
cont++;
}
if (r>n/ 2)
{
l++; r = 1;
}
}
if (n == 1)
{
puts("YES");
cout << a[1] << endl;
return 0;
}
int ttt[410], tmp = 0;
memset(ttt, 0, sizeof(ttt));
if (n % 2)
{
int tt;
for (int i = 1; i <= n*n; i++)
{
if (mp[a[i]]>=2)
{
mp[a[i]] -= 2;
ttt[++tmp] = a[i];
}
}
for (int i = 1; i <= n*n; i++)
{
if (mp[a[i]] == 1)
{
tt = a[i];
break;
}
}
for (int i = 1; i <= n / 2; i++)
{
for (int j = 1; j <= (n) / 2; j++)
{
if (ans[i][j] == 0)
{
puts("NO");
return 0;
}
}
}
for (int i = 1; i < n / 2 * 2; i++)
{
if (ttt[i] == 0)
{
{
puts("NO");
return 0;
}
}
}
puts("YES");
int sss = 1;
for (int i = 1; i <= n / 2; i++)
{
int j;
for (j = 1; j <= n / 2; j++)
cout << ans[i][j] << " ";
cout << ttt[sss++] << " ";
for (j = j - 1; j >= 1; j--)
cout << ans[i][j] << " ";
cout << endl;
}
for (int i = 1; i <= n / 2; i++)
cout << ttt[sss++] << " ";
cout << tt << " ";
sss--;
for (int i = n / 2; i >= 1; i--)
cout << ttt[sss--] << " ";
cout << endl;
//sss = sss;
for (int i = 1; i <= n / 2; i++)
{
int j;
for (j = 1; j <= n / 2; j++)
cout << ans[n / 2 - i + 1][j] << " ";
cout << ttt[sss--] << " ";
for (j = j - 1; j >= 1; j--)
cout << ans[n / 2 - i + 1][j] << " ";
cout << endl;
}
}
else
{
for (int i = 1; i <= (n) / 2; i++)
{
for (int j = 1; j <= (n) / 2; j++)
{
if (ans[i][j] == 0)
{
puts("NO");
return 0;
}
}
}
puts("YES");
for (int i = 1; i <= n / 2; i++)
{
int j;
for (j = 1; j <= (n + 1) / 2; j++)
cout << ans[i][j] << " ";
for (j = j - 1; j >= 1; j--)
cout << ans[i][j] << " ";
cout << endl;
}
for (int i = 1; i <= n / 2; i++)
{
int j;
for (j = 1; j <= (n + 1) / 2; j++)
cout << ans[n / 2 - i + 1][j] << " ";
for (j = j - 1; j >= 1; j--)
cout << ans[n / 2 - i + 1][j] << " ";
cout << endl;
}
}
return 0;
}
D1,D2 Coffee and Coursework
题意都一样的,只是数据范围不同,给出n个数,和一个m,一天之内可以选n个数,但不过除了第一数是原来的数,此后每一个数都要在,原来的基础上依次减去1,2,3.......,问我们最少多少天能选出来的得到的数加起来大于等于m.首先我们看到D1的数据比较小,答案,肯定在1到n之间,所以我们可以枚举天数得到答案,D2数据比较大,我们这样想如果a天完成了,那a+1天就一定能完成,因此我们采用二分的方法,逼近最小的天数,具体代码如下,注意细节:
///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
const int N=110;
ll n,m;
ll a[200010];
bool cmp(ll a,ll b)
{
return a>b;
}
bool judge(ll i)
{
if(i==0)
return false;
ll tmp=0,s=0;
for(int j=1;j<=n;j++)
{
if(tmp>a[j])
break;
s+=a[j]-tmp;
if(j%i==0)
tmp++;
}
if(s>=m)
return true;
return false;
}
int main()
{
cin>>n>>m;
ll sum=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i];
}
if(sum<m)
{
cout<<"-1"<<endl;
return 0;
}
sort(a+1,a+n+1,cmp);
ll l=1,r=n;
ll ans;
while(l<=r)
{
int mid=(l+r)>>1;
if(judge(mid)&&!judge(mid-1))
{
ans=mid;
break;
}
if(judge(mid))
r=mid-1;
else
l=mid+1;
}
cout<<ans<<endl;
return 0;
}
E Yet Another Ball Problem
题意:这道题实际上不是很难,给你两个数,n和k,题意叫你列出从1到k中选出2个数的排列,但不过这些排序的排序与摆放要满足题上的要求,直到摆放完n个位置,做法很简单,依次枚举,对每一个可以交换顺序在放一次。
///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
const int N=200010;
long long n,k;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>k;
long long cnt=0;
if(k*(k-1)<n)
{
cout<<"NO"<<endl;
return 0;
}
cout<<"YES"<<endl;
for(int i=1;i<=k-1;i++)
{
for(int j=i+1;j<=k;j++)
{
cout<<i<<" "<<j<<endl;
cnt++;
if(cnt!=n)
{
cout<<j<<" "<<i<<endl;
cnt++;
}
if(cnt==n)
return 0;
}
}
return 0;
}
F1,Tree Cutting (Easy Version)
困难版本跨度太大,还不会,题意:给你一棵树,同时给出每个点的颜色,有三种,一种是红,一种是蓝色,一种是为染色,给出一个美丽的边的定义:删除那条边,剩下的两部分中,除去未染色,只能有一种颜色,做法也很暴力,先标记每一个结点的颜色情况,然后DFS任选一个根暴力搜索,更新每一个子树的颜色情况,同时判断连接的边是否满足条件。
///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N=300010;
vector<int>g[N];
int n,col[N][3],vis[N],ans,cnt1,cnt2;
void dfs(int x)
{
vis[x]=1;
for(int i=0;i<g[x].size();i++)
{
int v=g[x][i];
if(!vis[v])
{
dfs(v);
col[x][0]+=col[v][0];
col[x][1]+=col[v][1];
col[x][2]+=col[v][2];
}
}
int p11=col[x][1],p12=col[x][2];
int p21=cnt1-col[x][1],p22=cnt2-col[x][2];
if(!(p11>0&&p12>0)&&!(p21>0&&p22>0)&&x!=1)
ans++;
}
int main()
{
FAST;
cin>>n;
int x;cnt1=cnt2=0;
memset(col,0,sizeof(col));
for(int i=1;i<=n;i++)
{
cin>>x;
if(x==1)
cnt1++;
if(x==2)
cnt2++;
col[i][x]=1;
}
int u,v;
for(int i=1;i<=n-1;i++)
{
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
memset(vis,0,sizeof(vis));
ans=0;
dfs(1);
cout<<ans<<endl;
return 0;
}