A.Useful Decomposition Codeforces 981C
题意:给你一棵N个结点的树,然后输入N-1条边。要求将该树拆成若干条简单路径,并且这些路径都经过一个公共节点。给出任意一个解决方案,如不存在输出No
思路:邻接表存图建双向边,如果一个点的出度>2,那么他就是那个共享的点,如果有两个共享的点,一定为NO。
我们把出度为1的点,存到一个数组中。如果有共享点,直接输出:共享点~这个数组中所有的点即可。
如果没有共享点,那么就是一条链的情况,输出两个出度为1的点即可。
#include
using namespace std;
const int MAXN = 100005;
int n, xx;
vector<int> G[MAXN], s;
int main()
{
scanf("%d", &n);
for (int i = 0; i < n-1; i++)
{
int u, v; scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
vector<int> x;
int cnt = 0, s = 0;
for (int i = 1; i <= n; i++)
{
if (G[i].size() == 1) x.push_back(i);
if (G[i].size() > 2) s = i, cnt++;
}
if (cnt >= 2) printf("No\n");
else
{
printf("Yes\n");
if (s == 0)//没有分叉点即一条链的情况
{
printf("%d\n", 1);
printf("%d %d\n", x[0], x[1]);
}
else
{
printf("%d\n", x.size());
for (auto i: x) printf("%d %d\n", s, i);
}
}
return 0;
}
C - Kefa and Park Codeforces 580C
#include
#include
#include
#include
using namespace std;
const int MAXN = 1e5 + 10;
int hasCat[MAXN], vis[MAXN];
int n, m, ans;
vector<int> G[MAXN];
int dfs(int cur, int ret) {
if(hasCat[cur]) {ret++;}
else {ret = 0;}
if(ret > m || vis[cur]) {return 0;}
vis[cur] = 1;
int ans = 0;
if(cur > 1 && G[cur].size() == 1) {return 1;}
for(int i = 0; i < G[cur].size(); i++) {
ans += dfs(G[cur][i], ret);
}
return ans;
}
int main() {
//freopen("input.txt", "r", stdin);
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%d", &hasCat[i]);
}
int u, v;
for(int i = 1; i <= n - 1; i++) {
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1, 0);
printf("%d\n", dfs(1, 0));
//fclose(stdin);
return 0;
}
我写的dfsWA在了第8个样例,加上对n != 1的考虑后WA在了第9个样例。还没有到底为什么WA了,看下AC代码,发现在DFS时带上fa参数非常有用,可以避免第二次访问。(所以我为什么傻到没有弄个vis!!!)
E - Recursive Queries Codeforces 932B
#include
#define ll long long
using namespace std;
int ans[10][1000005],q,l,r,k;
int op(int x) //f(n)函数的功能实现
{
if(x<10)return x;
int tmp,as;
while(1)
{
as=1;
while(x)
{
tmp=x%10;
x/=10;
if(tmp)as*=tmp;
}
if(as<10)return as;
x=as;
}
}
int main()
{
for(int i=1;i<=9;i++)ans[i][0]=0;
for(int i=1;i<=9;i++) //前缀和打表
{
for(int j=1;j<=1000000;j++)
{
if(op(j)==i){ans[i][j]=ans[i][j-1]+1;}
else ans[i][j]=ans[i][j-1];
}
}
scanf("%d",&q);
while(q--) //在线查询
{
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",ans[k][r]-ans[k][l-1]);
}
return 0;
}
G - Okabe and Boxes Codeforces 821C
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define REP(i,a) for(int i = 0; i < (a); i++)
#define PB push_back
#define SZ(a) (a).size()
#define MP make_pair
#define ALL(a) (a).begin(),(a).end()
#define fs first
typedef vector<int> vi;
typedef pair<int,int> pii;
int main()
{
int n;
cin >> n;
stack<int> st;
int curr=1;
int ans = 0;
REP(i,2*n){
string str;
cin >> str;
assert(str[0]=='a' || str[0]=='r');
if(str[0]=='a'){
int x;
cin >> x;
st.push(x);
}else if(str[0]=='r'){
if(!st.empty()){
if(st.top()==curr){ //last thing added is what we need to remove
st.pop();
}else{ //last thing we added is NOT what we need to remove
ans++;
while(!st.empty()) st.pop(); //clears the stack
}
}
curr++;
}
}
cout << ans << endl;
}
I - Producing Snow Codeforces 948C
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N=1e5+5;
LL t[N],sum[N],v[N]; //sum[i]是t[i]的前缀和
int main(){
priority_queue<LL,vector<LL>,greater<LL> >q;
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&v[i]);
}
for(int i=1;i<=n;i++){
scanf("%lld",&t[i]);
sum[i]=t[i]+sum[i-1];
}
for(int i=1;i<=n;i++){
q.push(v[i]+sum[i-1]); //加上sum[i-1],可以在减的时候将前一段没有消融的sum[i-1]抵消掉
LL ans=t[i]*q.size(); //先假设没有一堆雪不够消融t[i]
while(!q.empty()&&q.top()<=sum[i]){ //找到不够t[i]的,减掉差值(不够的部分)
ans+=q.top()-sum[i];
q.pop();
}
printf("%lld%c",ans,i==n?'\n':' ');
}
return 0;
}