CCF 2016-09
CCF 历年题目集
A. 最大波动
#include
using namespace std;
const int N = 1005;
int a[N];
int main()
{
int n;
cin >> n;
for (int i = 0 ; i < n ; i ++ ) cin >> a[i];
int ans = 0;
for (int i = 1 ; i < n ; i ++ )
{
ans = max(ans,abs(a[i]-a[i-1]));
}
cout << ans << endl;
return 0;
}
B. 火车购票
用 vector 模拟每个车厢的座位,分成能在一排坐下和不能在一排坐下两种情况讨论
#include
using namespace std;
vector v[20];
int main()
{
int n;
cin >> n;
int c = 0;
for (int i = 0 ; i < 20 ; i ++ )
for (int j = 0 ; j < 5 ; j ++ )
v[i].push_back(++c);
int x;
for (int i = 0 ; i < n ; i ++ )
{
cin >> x;
for (int i = 0 ; i < 20 ; i ++ )
{
if(v[i].size() >= x)
{
while(x -- )
{
cout << v[i][0] << ' ';
v[i].erase(v[i].begin());
}
cout << endl;
}
}
if(x != -1)
{
for (int i = 0 ; i < 20 ; i ++ )
{
if(v[i].size())
{
while(x)
{
cout << v[i][0] << ' ';
v[i].erase(v[i].begin());
x -- ;
if(x == 0 || v[i].size() == 0) break;
}
}
if(x == 0)
{
cout << endl;
break;
}
}
}
}
return 0;
}
C. 炉石传说
按照题目模拟就行,注意召唤时和战斗死亡时要更改位置就行
#include
using namespace std;
struct Master
{
int health,attack;
}m1[1010],m2[1010];
int h1 = 30,h2 = 30;
int c1 , c2;
vector v1, v2;
int main()
{
int n;
cin >> n;
for (int i = 0 ; i < n ; i ++ )
{
string str;
while(cin >> str)
{
if(str == "end") break;
else if(str == "summon")
{
int pos,att,hea;
cin >> pos >> att >> hea;
if(i & 1)
{
// 若该位置有随从
for (int j = 7 ; j >= pos + 1 ; j -- )
{
m2[j] = m2[j-1];
}
m2[pos] = {hea,att};
}
else
{
// 若该位置有随从
for (int j = 7 ; j >= pos + 1; j -- )
{
m1[j] = m1[j-1];
}
m1[pos] = {hea,att};
}
}
else if(str == "attack")
{
int att,def;
cin >> att >> def;
if(i & 1)
{
if(def == 0) h1 -= m2[att].attack;
else
{
m2[att].health -= m1[def].attack;
m1[def].health -= m2[att].attack;
// 如果死亡
if(m2[att].health <= 0)
{
for (int i = att ; i <= 7 ; i ++ )
{
m2[i] = m2[i+1];
}
}
if(m1[def].health <= 0)
{
for (int i = def ; i <= 7 ; i ++ )
{
m1[i] = m1[i+1];
}
}
}
}
else
{
if(def == 0) h2 -= m1[att].attack;
else
{
m1[att].health -= m2[def].attack;
m2[def].health -= m1[att].attack;
// 如果死亡
if(m1[att].health <= 0)
{
for (int i = att ; i <= 7 ; i ++ )
{
m1[i] = m1[i+1];
}
}
if(m2[def].health <= 0)
{
for (int i = def ; i <= 7 ; i ++ )
{
m2[i] = m2[i+1];
}
}
}
}
}
}
}
if(h2 <= 0) puts("1");
else if(h1 <= 0) puts("-1");
else if(h1 && h2) puts("0");
cout << h1 << endl;
for (int i = 1 ; i <= 7 ; i ++ )
if(m1[i].health > 0) v1.push_back(m1[i].health);
cout << v1.size() << ' ';
for (auto c : v1) cout << c << ' ';
puts("");
cout << h2 << endl;
for (int i = 1 ; i <= 7 ; i ++ )
if(m2[i].health > 0) v2.push_back(m2[i].health);
cout << v2.size() << ' ';
for (auto c : v2) cout << c << ' ';
return 0;
}
D. 交通规划
先用 dijkstra 跑出各个点到 1 的最短距离,然后从其它顶点判断到 1 的距离,如果等于最短距离就加入
#include
using namespace std;
typedef pair pii;
const int N = 10010,M = 200010;
int n,m;
int h[N],w[M],e[M],ne[M],idx;
int dist[N];
bool st[N];
void add(int a,int b,int c)
{
e[idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx ++ ;
}
void dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1] = 0;
priority_queue,greater > heap;
heap.push({0,1});
while(heap.size())
{
auto t = heap.top();
heap.pop();
int ver = t.second, distance = t.first;
if(st[ver]) continue;
st[ver] = true;
for (int i = h[ver] ; ~i ; i = ne[i])
{
int j = e[i];
if(dist[j] > distance + w[i])
{
dist[j] = distance + w[i];
heap.push({dist[j],j});
}
}
}
return ;
}
int main()
{
memset(h,-1,sizeof h);
scanf("%d%d",&n,&m);
int a,b,c;
while(m -- )
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
dijkstra();
int res = 0;
// 倒着求解
for (int i = 2 ; i <= n ; i ++ )
{
int road = 0x3f3f3f3f;
for (int j = h[i] ; ~j ; j = ne[j])
{
int k = e[j];
if(dist[i] == dist[k] + w[j])
{
road = min(road,w[j]);
}
}
res += road;
}
printf("%d\n",res);
return 0;
}
E. 祭坛
暂时不会~