C - Canonical Coin Systems
A coin system SS is a finite (nonempty) set of distinct positive integers corresponding to coin values, also called denominations, in a real or imagined monetary system. For example, the coin system in common use in Canada is \{ 1,5,10,25,100,200\}{1,5,10,25,100,200}, where 11 corresponds to a 11-cent coin and 200200 corresponds to a 200200-cent (22-dollar) coin. For any coin system SS, we assume that there is an unlimited supply of coins of each denomination, and we also assume that SS contains 11, since this guarantees that any positive integer can be written as a sum of (possibly repeated) values in SS.
Cashiers all over the world face (and solve) the following problem: For a given coin system and a positive integer amount owed to a customer, what is the smallest number of coins required to dispense exactly that amount? For example, suppose a cashier in Canada owes a customer 8383 cents. One possible solution is 25+25+10+10+10+1+1+125+25+10+10+10+1+1+1, i.e., 88 coins, but this is not optimal, since the cashier could instead dispense 25+25+25+5+1+1+125+25+25+5+1+1+1, i.e., 77 coins (which is optimal in this case). Fortunately, the Canadian coin system has the nice property that the greedy algorithm always yields an optimal solution, as do the coin systems used in most countries. The greedy algorithm involves repeatedly choosing a coin of the largest denomination that is less than or equal to the amount still owed, until the amount owed reaches zero. A coin system for which the greedy algorithm is always optimal is called canonical.
Your challenge is this: Given a coin system S = \{ c_1, c_2, \ldots , c_ n\}S={c1,c2,…,cn}, determine whether SS is canonical or non-canonical. Note that if SS is non-canonical then there exists at least one counterexample, i.e., a positive integer xx such that the minimum number of coins required to dispense exactly xx is less than the number of coins used by the greedy algorithm. An example of a non-canonical coin system is \{ 1,3,4\}{1,3,4}, for which 66 is a counterexample, since the greedy algorithm yields 4+1+14+1+1 (33 coins), but an optimal solution is 3+33+3 (22 coins). A useful fact (due to Dexter Kozen and Shmuel Zaks) is that if SS is non-canonical, then the smallest counterexample is less than the sum of the two largest denominations.
Input
Input consists of a single case. The first line contains an integer nn (2 \leq n \leq 100)(2≤n≤100), the number of denominations in the coin system. The next line contains the nn denominations as space-separated integers c_1 \ c_2 \ \ldots \ c_ nc1 c2 … cn, where c_1 = 1c1=1 and c_1 < c_2 < \ldots < c_ n \leq 10^6c1<c2<…<cn≤106.
Output
Output “canonical” if the coin system is canonical, or “non-canonical” if the coin system is non-canonical.
Sample 1
Inputcopy | Outputcopy |
---|---|
4 1 2 4 8 | canonical |
Sample 2
Inputcopy | Outputcopy |
---|---|
3 1 5 8 | non-canonical |
Sample 3
Inputcopy | Outputcopy |
---|---|
6 1 5 10 25 100 200 | canonical |
队友写的,先用贪心算出方案,再用dp算出方案,如果两个方案有任何一个有出入的话就是不规范的。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10, INF = 0x3f3f3f3f;
int a[N];
long long dp[N];
int num[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
for (int i = 0; i < n; i++) cin>>a[i];
for (int i = 1; i <= 2000000; i++)
{
int money = i;
int k = n - 1;
while(money)
{
if(money >= a[k])
{
num[i] += money/a[k];
money %= a[k];
}
k--;
}
}
for(int i=1;i<N;i++) dp[i]=INF;
for (int i = 0; i < 2000000; i++)
for (int j = 0; j < n; j++)
if (i >= a[j])
dp[i] = min(dp[i], dp[i - a[j]] + 1);
int flag = 0;
for (int i = 1; i<2000000; i++)
{
if (dp[i] != num[i])
{
cout<<"non-canonical"<<endl;
flag = 1;
return 0;
}
}
cout<<"canonical"<<endl;
return 0;
}
F - GlitchBot
One of our delivery robots is malfunctioning! The job of the robot is simple; it should follow a list of instructions in order to reach a target destination. The list of instructions is originally correct to get the robot to the target. However, something is going wrong as we upload the instructions into the robot’s memory. During the upload, one random instruction from the list takes on a different value than intended. Yes, there is always a single bad instruction in the robot’s memory and it always results in the robot arriving at an incorrect destination as it finishes executing the list of instructions.
The robot can execute the instructions “Left”, “Right”, and “Forward”. The “Left” and “Right” instructions do not result in spatial movement but result in a 9090-degree turn in the corresponding direction. “Forward” is the only instruction that results in spatial movement, causing the robot to move one unit in the direction it is facing. The robot always starts at the origin (0,0)(0,0) of a grid and faces north along the positive y-axis.
Given the coordinates of the target destination and the list of instructions that the robot has in its memory, you are to identify a correction to the instructions to help the robot reach the proper destination.
Input
The first line of the input contains the xx and yy integer coordinates of the target destination, where -50 \leq x \leq 50−50≤x≤50 and -50 \leq y \leq 50−50≤y≤50. The following line contains an integer nn representing the number of instructions in the list, where 1 \leq n \leq 501≤n≤50. The remaining nn lines each contain a single instruction. These instructions may be: “Left”, “Forward”, or “Right”.
Output
Identify how to correct the robot’s instructions by printing the line number (starting at 11) of an incorrect input instruction, followed by an instruction substitution that would make the robot reach the target destination. If there are multiple ways to fix the instructions, report the fix that occurs for the earliest line number in the sequence of instructions. There is always exactly one unique earliest fix.
Sample 1
Inputcopy | Outputcopy |
---|---|
3 2 11 Forward Right Forward Forward Left Forward Forward Left Forward Right Forward | 8 Right |
Sample 2
Inputcopy | Outputcopy |
---|---|
-1 1 3 Right Left Forward | 1 Forwardh |
还是队友写的hh,暴力模拟,一个一个改
#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cstdio>
using namespace std;
#define IOS \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
string a[60];
string c[60];
string b[4];
char dirr[4] = {'n', 'w', 's', 'e'};
int x, y;
int n;
bool run(int k, int l)
{
for(int i=1;i<=n;i++)
{
c[i]=a[i];
}
int dir = 0;
int xx = 0, yy = 0;
for (int i = 1; i <= n; i++)
{
if (i == k)
{
c[i] = b[l];
}
if (c[i] == "Left")
{
dir += 1;
}
else if (c[i] == "Right")
{
dir -= 1;
}
else if(c[i]=="Forward")
{
if(dirr[dir]=='n')
yy++;
else if(dirr[dir]=='w')
xx--;
else if(dirr[dir]=='s')
yy--;
else if(dirr[dir]=='e')
xx++;
}
if (dir > 3)
dir -= 4;
else
{
if (dir < 0)
dir += 4;
}
}
if(xx==x&&yy==y)
return true;
return false;
}
int main()
{
cin >> x >> y;
cin >> n;
b[1] = "Left";
b[2] = "Right";
b[3] = "Forward";
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= 3; j++)
{
if (a[i] != b[j])
if (run(i, j))
{
cout<<i<<" "<<b[j]<<endl;
return 0;
}
}
}
return 0;
}
G - Greeting Card
Quido plans to send a New Year greeting to his friend Hugo. He has recently acquired access to an advanced high-precision plotter and he is planning to print the greeting card on the plotter.
Here’s how the plotter operates. In step one, the plotter plots an intricate pattern of nn dots on the paper. In step two, the picture in the greeting emerges when the plotter connects by a straight segment each pair of dots that are exactly 2\, 0182018 length units apart.
The plotter uses a special holographic ink, which has a limited supply. Quido wants to know the number of all plotted segments in the picture to be sure that there is enough ink to complete the job.
Input
The first line of input contains a positive integer nn specifying the number of plotted points. The following nn lines each contain a pair of space-separated integer coordinates indicating one plotted point. Each coordinate is non-negative and less than 2^{31}231. There are at most 10^{5}105 points, all of them are distinct.
In this problem, all coordinates and distances are expressed in plotter length units, the length of the unit in the x-direction and in the y-direction is the same.
Output
The output contains a single integer equal to the number of pairs of points which are exactly 2\, 0182018 length units apart.
Sample 1
Inputcopy | Outputcopy |
---|---|
4 20180000 20180000 20180000 20182018 20182018 20180000 20182018 20182018 | 4 |
Sample 2
Inputcopy | Outputcopy |
---|---|
6 0 0 1680 1118 3360 0 5040 1118 6720 0 8400 1118 | 5 |
思维题,距离是2018的就两大种情况,2018 0和1118 1680
#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cstdio>
#define INF 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define inf 0x3f3f3f3f3f3f3f3f
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for (auto i = a; i <= b; ++i)
#define bep(i, a, b) for (auto i = a; i >= b; --i)
#define lowbit(x) x &(-x)
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define PI acos(-1)
#define pb push_back
#define eps 1e-6
#define X1 first
#define Y1 second
#define IOS \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
const int MO = 1e9 + 10;
const int mod = 1e8 + 10;
const int MOD = 2e6 + 20;
const int N = 2e6 + 10;
const int M = 2e5 + 10;
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
int dxy[][2] = {{0, 1}, {1, 0}, {1, 1}, {-1, 1}};
using namespace std;
map <PLL,ll> m;
ll dir[12][2] = {2018,0,0,2018,-2018,0,0,-2018,1118,1680,-1118,1680,1118,-1680,-1118,-1680,1680,1118,1680,-1118,-1680,1118,-1680,-1118};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,ans = 0;
cin >> n;
for(int i = 0;i < n; i++)
{
ll x,y;
cin >> x >> y;
ans += m[{x,y}];
for(int i = 0;i < 12; i++)
m[{x + dir[i][0],y + dir[i][1]}]++;
}
cout << ans << endl;
return 0;
}
I - Odd Gnome
According to the legend of Wizardry and Witchcraft, gnomes live in burrows underground, known as gnome holes. There they dig up and eat the roots of plants, creating little heaps of earth around gardens, causing considerable damage to them.
Mrs. W, very annoyed by the damage, has to regularly de-gnome her garden by throwing the gnomes over the fence. It is a lot of work to throw them one by one because there are so many. Fortunately, the species is so devoted to their kings that each group always follows its king no matter what. In other words, if she were to throw just the king over the fence, all the other gnomes in that group would leave.
So how does Mrs. W identify the king in a group of gnomes? She knows that gnomes travel in a certain order, and the king, being special, is always the only gnome who does not follow that order.
Here are some helpful tips about gnome groups:
-
There is exactly one king in a group.
-
Except for the king, gnomes arrange themselves in strictly increasing ID order.
-
The king is always the only gnome out of that order.
-
The king is never the first nor the last in the group, because kings like to hide themselves.
Help Mrs. W by finding all the kings!
Input
The input starts with an integer nn, where 1 \leq n \leq 1001≤n≤100, representing the number of gnome groups. Each of the nn following lines contains one group of gnomes, starting with an integer gg, where 3 \leq g \leq 1\, 0003≤g≤1000, representing the number of gnomes in that group. Following on the same line are gg space-separated integers, representing the gnome ordering. Within each group all the integers (including the king) are unique and in the range [0,10\, 000][0,10000]. Excluding the king, each integer is exactly one more than the integer preceding it.
Output
For each group, output the king’s position in the group (where the first gnome in line is number one).
Sample 1
Inputcopy | Outputcopy |
---|---|
3 7 1 2 3 4 8 5 6 5 3 4 5 2 6 4 10 20 11 12 | 5 4 2 |
签到题,但是还是有点小坑和细节需要注意的
/*Where there is light, in my heart.*/
/*SUMMER_TRAINING DAY 22*/
#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
//
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//#define INF 0x3f3f3f
#define ll long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define unmap(a,b) unordered_map<a,b>
#define unset(a) unordered_set<a>
#define F first
#define S second·
#define pb push_back
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
#define mode 1e4+7
#define pi acos(-1)
typedef double db;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef vector<int> vi;
const int N=2e5+5;
//
int a[10005];
int n;
int flag;
int t;
signed main(){
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for (int i = 2; i < n; i++)
if ((a[i] > a[i + 1] && a[i] > a[i - 1] && a[i - 1] < a[i + 1] )|| ( a[i - 1] < a[i + 1]&& a[i] < a[i + 1] && a[i] < a[i - 1]))
{
flag=i;
}
cout<<flag<<endl;
}
}
//made by shun 20220725
J - Progressive Scramble
You are a member of a naive spy agency. For secure communication, members of the agency use a very simple encryption algorithm – which changes each symbol in the message ‘progressively’, i.e., based on the symbols preceding it. The allowed symbols are space and the 2626 lowercase English letters. For encryption purposes we assign them the values 00 (for space) and 11 through 2626 (for a–z). We’ll let v(s)v(s) represent the numeric value of symbol ss.
Consider a message with symbols s_1, s_2, \ldots , s_ ns1,s2,…,sn. The encryption algorithm starts by converting the first symbol s_1s1 into its associated value u_1 = v(s_1)u1=v(s1). Then for each subsequent symbol s_ isi in the message, the computed value is u_ i = v(s_ i) + u_{i-1}ui=v(si)+ui−1 — the sum of its associated value and the computed value for the previous symbol. (Note that when there is a space in the input message, the previous scrambled letter is repeated.) This process continues until all the u_ iui are computed.
At this point, the message is a sequence of numeric values. We need to convert it back to symbols to print it out. We do this by taking the value u_ iui modulo 2727 (since there are 2727 valid symbols), and replacing that value with its corresponding symbol. For example, if u_ i=32ui=32, then 32 \bmod 27 = 532mod27=5, which is the symbol ‘e’ (since v(e) = 5v(e)=5).
Let’s look at an example. Suppose we want to encrypt the string “my pie”.
-
First, convert each symbol s_ isi into v(s_ i)v(si): [13, 25, 0, 16, 9, 5][13,25,0,16,9,5].
-
Next, compute each u_ iui: [13, 38, 38, 54, 63, 68][13,38,38,54,63,68].
-
Then, use modulus on the u_ iui: [13, 11, 11, 0, 9, 14][13,11,11,0,9,14].
-
Finally, convert these back to symbols: “mkk in”.
Create a program that takes text and encrypts it using this algorithm, and also decrypts text that has been encrypted with this algorithm.
Input
The input to your program consists of a single integer 1 \le n \le 1001≤n≤100 on its own line. This number is followed by nn lines, each containing the letter ‘e’ or ‘d’, a single space, and then a message made up of lowercase letters (a–z) and spaces, continuing to the end of the line. Each message is between 11 and 8080 characters long. The letters ‘d’ and ‘e’ indicate that your program decrypts or encrypts the subsequent string, respectively.
Output
Output the result of encrypting or decrypting each message from the input on its own separate line. Note that differences in whitespace are significant in this problem. Therefore your output must match the correct output character-for-character, including spaces.
Sample 1
Inputcopy | Outputcopy |
---|---|
7 e testing multiple letters rrrrrrrrrrrrr e this particularly long sentence can test encryption d tajbbrsjcloiuvmywwhwjqqqinauzmpuuxyllejbvv nqhfvoxlz e my pie d mkk in e the quick brown fox jumps over the lazy dog d taffwqzbmmofuqddjyvvezlatthchzzs eeqrqoosgn | tyqjsfmmzteygwhmmycwpulddvmdvmdvmdvmdv tajbbrsjcloiuvmywwhwjqqqinauzmpuuxyllejbvv nqhfvoxlz this particularly long sentence can test encryption mkk in my pie taffwqzbmmofuqddjyvvezlatthchzzs eeqrqoosgn the quick brown fox jumps over the lazy dog |
一道比较麻烦的模拟题,加密比较好想,解密部分是逆推,可以一直减27逆序取模的过程,这里不是很好想,还有要注意格式里的空格之类的东西
/*Where there is light, in my heart.*/
/*SUMMER_TRAINING DAY 22*/
#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
//
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//#define INF 0x3f3f3f
#define ll long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define unmap(a,b) unordered_map<a,b>
#define unset(a) unordered_set<a>
#define F first
#define S second·
#define pb push_back
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
#define mode 1e4+7
#define pi acos(-1)
typedef double db;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef vector<int> vi;
const int N=2e5+5;
//
int num[1005];
int sum[1005];
//
signed main(){
int t;
char order;
cin>>t;
while(t--){
cin>>order;
getchar();
mem(num,0);
mem(sum,0);
string s,ans;
getline(cin,s);
int len=s.size();
for(int i=0;i<len;i++){
if(s[i]==' ') sum[i]=0;
else sum[i]=s[i]-'a'+1;
}
if(order=='e'){
for(int i=1;i<len;i++){
sum[i]=(sum[i]+sum[i-1])%27;
}
}
else if(order=='d'){
for(int i=1;i<len;i++){
num[i]=num[i-1]+sum[i-1];
while(sum[i]<num[i]){
sum[i]+=27;
}
sum[i]=(sum[i]-num[i])%27;
}
}
for(int i=0;i<len;i++){
if(sum[i]==0) ans+=' ';
else ans+=sum[i]+'a'-1;
}
cout<<ans<<endl;
}
}
//made by shun 20220725
B - Bumped!
Peter returned from the recently held ACM ICPC World Finals only to find that his return flight was overbooked and he was bumped from the flight! Well, at least he wasn’t beat up by the airline and he’s received a voucher for one free flight between any two destinations he wishes.
He is already planning next year’s trip. He plans to travel by car where necessary, but he may be using his free flight ticket for one leg of the trip. He asked for your help in his planning.
He can provide you a network of cities connected by roads, the amount it costs to buy gas for traveling between pairs of cities, and a list of available flights between some of those cities. Help Peter by finding the minimum amount of money he needs to spend to get from his hometown to next year’s destination!
Input
The input consists of a single test case. The first line lists five space-separated integers nn, mm, ff, ss, and tt, denoting the number of cities nn (0 < n \le 50\, 0000<n≤50000), the number of roads mm (0 \le m \le 150\, 0000≤m≤150000), the number of flights ff (0 \le f \le 1\, 0000≤f≤1000), the number ss (0 \le s < n0≤s<n) of the city in which Peter’s trip starts, and the number tt (0 \le t < n0≤t<n) of the city Peter is trying to travel to. (Cities are numbered from 00 to n-1n−1.)
The first line is followed by mm lines, each describing one road. A road description contains three space-separated integers ii, jj, and cc (0 \le i, j < n, i \ne j0≤i,j<n,i=j and 0 < c \le 50\, 0000<c≤50000), indicating there is a road connecting cities ii and jj that costs cc cents to travel. Roads can be used in either direction for the same cost. All road descriptions are unique.
Each of the following ff lines contains a description of an available flight, which consists of two space-separated integers uu and vv (0 \le u, v < n0≤u,v<n, u \ne vu=v) denoting that a flight from city uu to city vv is available (though not from vv to uu unless listed elsewhere). All flight descriptions are unique.
Output
Output the minimum number of cents Peter needs to spend to get from his home town to the competition, using at most one flight. You may assume that there is a route on which Peter can reach his destination.
Sample 1
Inputcopy | Outputcopy |
---|---|
8 11 1 0 5 0 1 10 0 2 10 1 2 10 2 6 40 6 7 10 5 6 10 3 5 15 3 6 40 3 4 20 1 4 20 1 3 20 4 7 | 45 |
Sample 2
Inputcopy | Outputcopy |
---|---|
8 11 1 0 5 0 1 10 0 2 10 1 2 10 2 6 40 6 7 10 5 6 10 3 5 15 3 6 40 3 4 20 1 4 20 1 3 30 4 7 | 50 |
地杰斯特拉加优先队列,最多使用一张机票,那就跑f+1遍迪杰斯特拉,找出最小值。注意使用优化版的dijkstra。
网上的码 自己还没敲
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = 1e10;
const ll maxn = 150010;
struct node
{
int v;
ll c;
node(int _v = 0,int _c = 0) : v(_v),c(_c){}
bool operator < (const node &r) const
{
return c > r.c;
}
};
struct Edge
{
int v;
ll cost;
Edge(int _v = 0,ll _cost = 0) : v(_v),cost(_cost) {}
};
vector<Edge>E[maxn];
bool vis[maxn];
ll dist[maxn];
void Dijkstra(int n,int start)
{
memset(vis,0, sizeof(vis));
for(int i = 0;i < n; i++)
dist[i] = inf;
priority_queue<node>que;
while(!que.empty())
que.pop();
dist[start] = 0;
que.emplace(node(start,0));
node tmp;
while(!que.empty())
{
tmp = que.top();
que.pop();
int u = tmp.v;
if(vis[u])
continue;
vis[u] = true;
for(int i = 0;i < E[u].size(); i++)
{
int v = E[u][i].v;
ll cost = E[u][i].cost;
if(!vis[v] && dist[v] > dist[u] + cost)
{
dist[v] = dist[u] + cost;
que.emplace(node(v,dist[v]));
}
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m,f,s,t;
cin >> n >> m >> f >> s >> t;
for(int i = 0;i < m; i++)
{
int u,v,w;
cin >> u >> v >> w;
E[u].emplace_back(Edge(v,w));
E[v].emplace_back(Edge(u,w));
}
ll minn = inf;
Dijkstra(n,s);
minn = min(minn,dist[t]);
for(int i = 0;i < f; i++)
{
int x,y;
cin >> x >> y;
E[x].emplace_back(Edge(y,0));
Dijkstra(n,s);
minn = min(minn,dist[t]);
E[x].erase(E[x].end() - 1);
}
cout << minn << endl;
return 0;
}
总结:这场难度相对大,两个模拟题比较费精力,队友做的效率明显高于自己,读题感觉有点懵