Open In App

Penalty scoring

Last Updated : 11 Dec, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Divyansh, while attending Geeks Classes, aims to solve all weekly contest problems. However, due to wrong submissions, he sometimes receives penalties, and each penalty reduces his score for that question by 10%. He requested the GeeksClasses team to provide all his contest scores as a linked list. The linked list is given as an array arr[], with each element representing a node.
The team now wants him to maximize this list based on specific rules:

  • If two consecutive equal values appear just before a 100, then the second value is increased by 10% (floor value), and the first value is converted to 100.
  • After applying all such updates, all nodes with value 100 must be moved to the end of the list, strictly by rearranging pointers (no new node creation).

Our task is to modify the linked list according to these rules and return the final updated list.

Example:

Input: arr[] = [75, 59, 84, 84, 100, 90]
Output: 75 -> 59 -> 92 -> 90 -> 100 -> 100
Explanation: The two equal numbers 84 and 84 appear just before 100, so the first 84 becomes 100 and the second becomes 84 + 10% = 92. After processing, all 100s are moved to the end, giving the final list: 75 -> 59 -> 92 -> 90 ->100 ->100.

Input: arr[] = [40, 70, 70, 100, 55, 55, 100, 80]
Output: 40 -> 70 -> 77 -> 55 -> 60 -> 80 -> 100 -> 100
Explanation: In the array, the consecutive values 70 and 70 appear just before a 100. Following the rules, the first 70 remains, and the second 70 is increased by 10% (floor value), becoming 77. Similarly, the consecutive 55 and 55 before a 100 are processed: the first 55 remains, and the second 55 becomes 60. After applying all updates, all nodes with value 100 are moved to the end of the list by rearranging pointers.

[Naive Approach] Full Scan and Fix - O(n^2) Time and O(1) Space

We scan the entire list again and again by looking for two equal numbers that come right before 100. If we find such a pair, we will change the first number to 100 and increase the second number by 10% (floor value). After applying this in entire linked list we make one final pass to move all 100s to the end by adjusting pointers.

C++
#include <iostream>
#include <vector>
using namespace std;

// Node structure for Linked List
struct Node {
    int data;
    Node* next;
    Node(int x) : data(x), next(nullptr) {}
};

// Apply the rule: if X -> X -> 100 appears, update values
void applyRule(Node* head) {
    Node* p = head;
    while (p && p->next && p->next->next) {
        if (p->data == p->next->data && p->next->next->data == 100) {
            // First X becomes 100
            p->data = 100;

            // Second X increases by 10% (floor)
            p->next->data = p->next->data + (p->next->data / 10);

            // Move pointer past the updated nodes
            p = p->next->next;
        } else {
            p = p->next;
        }
    }
}

// Move all nodes with value 100 to the end
Node* moveHundreds(Node* head) {
    Node* dummy = new Node(-1);
    dummy->next = head;

    Node* prev = dummy;
    Node* curr = head;
    Node* hundredHead = nullptr;
    Node* hundredTail = nullptr;

    while (curr) {
        if (curr->data == 100) {
            // Remove current 100 from list
            prev->next = curr->next;
            curr->next = nullptr;

            // Append to 100s list
            if (!hundredHead) {
                hundredHead = hundredTail = curr;
            } else {
                hundredTail->next = curr;
                hundredTail = curr;
            }

            curr = prev->next;
        } else {
            prev = curr;
            curr = curr->next;
        }
    }

    // Attach all 100s at the end
    prev->next = hundredHead;
    return dummy->next;
}

Node* maximizeScores(vector<int>& arr) {
    if (arr.empty()) return nullptr;

    // Build linked list from array
    Node* head = new Node(arr[0]);
    Node* temp = head;
    for (size_t i = 1; i < arr.size(); i++) {
        temp->next = new Node(arr[i]);
        temp = temp->next;
    }

    // Apply the X -> X -> 100 rule
    applyRule(head);

    // Move all 100s to the end
    return moveHundreds(head);
}

// Helper function to print linked list
void printList(Node* head) {
    Node* temp = head;
    while (temp) {
        cout << temp->data;
        if (temp->next) cout << " -> ";
        temp = temp->next;
    }
    cout << endl;
}

int main() {
    vector<int> arr = {75, 59, 84, 84, 100, 90};

    Node* head = maximizeScores(arr);

    printList(head); 

    return 0;
}
Java
import java.util.Arrays;

class Node {
    int data;
    Node next;
    Node(int x) { data = x; next = null; }
}

public class GFG {

    // Apply the rule: if X -> X -> 100 appears, update values
    static void applyRule(Node head) {
        Node p = head;
        while (p != null && p.next != null && p.next.next != null) {
            if (p.data == p.next.data && p.next.next.data == 100) {
                // First X becomes 100
                p.data = 100;

                // Second X increases by 10% (floor)
                p.next.data = p.next.data + (p.next.data / 10);

                // Move pointer past the updated nodes
                p = p.next.next;
            } else {
                p = p.next;
            }
        }
    }

    // Move all nodes with value 100 to the end
    static Node moveHundreds(Node head) {
        Node dummy = new Node(-1);
        dummy.next = head;

        Node prev = dummy;
        Node curr = head;
        Node hundredHead = null;
        Node hundredTail = null;

        while (curr != null) {
            if (curr.data == 100) {
                // Remove current 100 from list
                prev.next = curr.next;
                curr.next = null;

                // Append to 100s list
                if (hundredHead == null) {
                    hundredHead = hundredTail = curr;
                } else {
                    hundredTail.next = curr;
                    hundredTail = curr;
                }

                curr = prev.next;
            } else {
                prev = curr;
                curr = curr.next;
            }
        }

        // Attach all 100s at the end
        prev.next = hundredHead;
        return dummy.next;
    }

    static Node maximizeScores(int[] arr) {
        if (arr.length == 0) return null;

        // Build linked list from array
        Node head = new Node(arr[0]);
        Node temp = head;
        for (int i = 1; i < arr.length; i++) {
            temp.next = new Node(arr[i]);
            temp = temp.next;
        }

        // Apply the X -> X -> 100 rule
        applyRule(head);

        // Move all 100s to the end
        return moveHundreds(head);
    }

    // Helper function to print linked list
    static void printList(Node head) {
        Node temp = head;
        while (temp != null) {
            System.out.print(temp.data);
            if (temp.next != null) System.out.print(" -> ");
            temp = temp.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {75, 59, 84, 84, 100, 90};
        Node head = maximizeScores(arr);
        printList(head);
    }
}
Python
# Node structure for Linked List
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

# Apply the rule: if X -> X -> 100 appears, update values
def applyRule(head):
    p = head
    while p and p.next and p.next.next:
        if p.data == p.next.data and p.next.next.data == 100:
            # First X becomes 100
            p.data = 100

            # Second X increases by 10% (floor)
            p.next.data = p.next.data + (p.next.data // 10)

            # Move pointer past the updated nodes
            p = p.next.next
        else:
            p = p.next

# Move all nodes with value 100 to the end
def moveHundreds(head):
    dummy = Node(-1)
    dummy.next = head

    prev = dummy
    curr = head
    hundredHead = None
    hundredTail = None

    while curr:
        if curr.data == 100:
            # Remove current 100 from list
            prev.next = curr.next
            curr.next = None

            # Append to 100s list
            if hundredHead is None:
                hundredHead = hundredTail = curr
            else:
                hundredTail.next = curr
                hundredTail = curr

            curr = prev.next
        else:
            prev = curr
            curr = curr.next

    # Attach all 100s at the end
    prev.next = hundredHead
    return dummy.next

def maximizeScores(arr):
    if not arr:
        return None

    # Build linked list from array
    head = Node(arr[0])
    temp = head
    for val in arr[1:]:
        temp.next = Node(val)
        temp = temp.next

    # Apply the X -> X -> 100 rule
    applyRule(head)

    # Move all 100s to the end
    return moveHundreds(head)

# Helper function to print linked list
def printList(head):
    temp = head
    res = []
    while temp:
        res.append(str(temp.data))
        temp = temp.next
    print(" -> ".join(res))

if __name__ == "__main__":
    arr = [75, 59, 84, 84, 100, 90]
    head = maximizeScores(arr)
    printList(head)
C#
using System;

class Node {
    public int data;
    public Node next;
    public Node(int x) { data = x; next = null; }
}

class Solution {

    // Apply the rule: if X -> X -> 100 appears, update values
    static void applyRule(Node head) {
        Node p = head;
        while (p != null && p.next != null && p.next.next != null) {
            if (p.data == p.next.data && p.next.next.data == 100) {
                // First X becomes 100
                p.data = 100;

                // Second X increases by 10% (floor)
                p.next.data = p.next.data + (p.next.data / 10);

                // Move pointer past the updated nodes
                p = p.next.next;
            } else {
                p = p.next;
            }
        }
    }

    // Move all nodes with value 100 to the end
    static Node moveHundreds(Node head) {
        Node dummy = new Node(-1);
        dummy.next = head;

        Node prev = dummy;
        Node curr = head;
        Node hundredHead = null;
        Node hundredTail = null;

        while (curr != null) {
            if (curr.data == 100) {
                // Remove current 100 from list
                prev.next = curr.next;
                curr.next = null;

                // Append to 100s list
                if (hundredHead == null) {
                    hundredHead = hundredTail = curr;
                } else {
                    hundredTail.next = curr;
                    hundredTail = curr;
                }

                curr = prev.next;
            } else {
                prev = curr;
                curr = curr.next;
            }
        }

        // Attach all 100s at the end
        prev.next = hundredHead;
        return dummy.next;
    }

    static Node maximizeScores(int[] arr) {
        if (arr.Length == 0) return null;

        // Build linked list from array
        Node head = new Node(arr[0]);
        Node temp = head;
        for (int i = 1; i < arr.Length; i++) {
            temp.next = new Node(arr[i]);
            temp = temp.next;
        }

        // Apply the X -> X -> 100 rule
        applyRule(head);

        // Move all 100s to the end
        return moveHundreds(head);
    }

    // Helper function to print linked list
    static void printList(Node head) {
        Node temp = head;
        while (temp != null) {
            Console.Write(temp.data);
            if (temp.next != null) Console.Write(" -> ");
            temp = temp.next;
        }
        Console.WriteLine();
    }

    static void Main() {
        int[] arr = {75, 59, 84, 84, 100, 90};
        Node head = maximizeScores(arr);
        printList(head);
    }
}
JavaScript
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

// Apply the rule: if X -> X -> 100 appears, update values
function applyRule(head) {
    let p = head;
    while (p && p.next && p.next.next) {
        if (p.data === p.next.data && p.next.next.data === 100) {
            // First X becomes 100
            p.data = 100;

            // Second X increases by 10% (floor)
            p.next.data = p.next.data + Math.floor(p.next.data / 10);

            // Move pointer past the updated nodes
            p = p.next.next;
        } else {
            p = p.next;
        }
    }
}

// Move all nodes with value 100 to the end
function moveHundreds(head) {
    let dummy = new Node(-1);
    dummy.next = head;

    let prev = dummy;
    let curr = head;
    let hundredHead = null;
    let hundredTail = null;

    while (curr) {
        if (curr.data === 100) {
            // Remove current 100 from list
            prev.next = curr.next;
            curr.next = null;

            // Append to 100s list
            if (!hundredHead) {
                hundredHead = hundredTail = curr;
            } else {
                hundredTail.next = curr;
                hundredTail = curr;
            }

            curr = prev.next;
        } else {
            prev = curr;
            curr = curr.next;
        }
    }

    // Attach all 100s at the end
    prev.next = hundredHead;
    return dummy.next;
}

function maximizeScores(arr) {
    if (arr.length === 0) return null;

    // Build linked list from array
    let head = new Node(arr[0]);
    let temp = head;
    for (let i = 1; i < arr.length; i++) {
        temp.next = new Node(arr[i]);
        temp = temp.next;
    }

    // Apply the X -> X -> 100 rule
    applyRule(head);

    // Move all 100s to the end
    return moveHundreds(head);
}

// Helper function to print linked list
function printList(head) {
    let temp = head;
    let res = [];
    while (temp) {
        res.push(temp.data);
        temp = temp.next;
    }
    console.log(res.join(" -> "));
}

// Example
let arr = [75, 59, 84, 84, 100, 90];
let head = maximizeScores(arr);
printList(head);

Output
75 -> 59 -> 92 -> 90 -> 100 -> 100

[Optimised Approach] Single Pass Linked List Adjustment - O(n) Time and O(1) Space

The ides is we traverse the linked list just once. Whenever we encounter two consecutive equal numbers immediately followed by a 100, we update the first number to 100 and increase the second number by 10% (taking the floor value). While doing this, we continue scanning the entire list to ensure every 100 is accounted for. After applying all updates, we move all nodes with the value 100 to the end of the linked list, strictly by rearranging the pointers, preserving the original relative order of the other elements.

C++
#include <iostream>
#include <vector>
using namespace std;

// Node structure for Linked List
struct Node {
    int data;
    Node* next;
    Node(int x) : data(x), next(nullptr) {}
};

// Apply the rule: if X -> X -> 100 appears, update values
void applyRule(Node* head) {
    Node* curr = head;
    while (curr && curr->next && curr->next->next) {
        if (curr->data == curr->next->data && curr->next->next->data == 100) {
            // First X becomes 100
            curr->data = 100;

            // Second X increases by 10% (floor)
            curr->next->data += curr->next->data / 10;
        }
        curr = curr->next;
    }
}

// Move all nodes with value 100 to the end
Node* moveHundreds(Node* head) {
    Node* dummy = new Node(-1);
    dummy->next = head;

    Node* prev = dummy;
    Node* curr = head;
    Node* hundredHead = nullptr;
    Node* hundredTail = nullptr;

    while (curr) {
        if (curr->data == 100) {
            // Remove 100 node
            prev->next = curr->next;
            curr->next = nullptr;

            // Append to 100s list
            if (!hundredHead) hundredHead = hundredTail = curr;
            else { hundredTail->next = curr; hundredTail = curr; }

            curr = prev->next;
        } else {
            prev = curr;
            curr = curr->next;
        }
    }

    // Attach 100s at the end
    prev->next = hundredHead;
    return dummy->next;
}

// Build linked list from array, apply rules, move 100s
Node* maximizeScores(vector<int>& arr) {
    if (arr.empty()) return nullptr;

    // Build linked list
    Node* head = new Node(arr[0]);
    Node* temp = head;
    for (size_t i = 1; i < arr.size(); i++) {
        temp->next = new Node(arr[i]);
        temp = temp->next;
    }

    // Apply X -> X -> 100 rule
    applyRule(head);

    // Move all 100s to the end
    return moveHundreds(head);
}

// Helper function to print linked list
void printList(Node* head) {
    Node* temp = head;
    while (temp) {
        cout << temp->data;
        if (temp->next) cout << " -> ";
        temp = temp->next;
    }
    cout << endl;
}

int main() {
    vector<int> arr = {75, 59, 84, 84, 100, 90};
    Node* head = maximizeScores(arr);
    printList(head);

    return 0;
}
Java
import java.util.Arrays;

// Node structure for Linked List
class Node {
    int data;
    Node next;
    Node(int x) { data = x; next = null; }
}

public class GFG {

    // Apply the rule: if X -> X -> 100 appears, update values
    static void applyRule(Node head) {
        Node curr = head;
        while (curr != null && curr.next != null && curr.next.next != null) {
            if (curr.data == curr.next.data && curr.next.next.data == 100) {
                
                // First X becomes 100
                curr.data = 100;
                // Second X increases by 10% (floor)
                curr.next.data += curr.next.data / 10;
            }
            curr = curr.next;
        }
    }

    // Move all nodes with value 100 to the end
    static Node moveHundreds(Node head) {
        Node dummy = new Node(-1);
        dummy.next = head;
        Node prev = dummy, curr = head;
        Node hundredHead = null, hundredTail = null;

        while (curr != null) {
            if (curr.data == 100) {
                prev.next = curr.next;
                curr.next = null;
                if (hundredHead == null) hundredHead = hundredTail = curr;
                else { hundredTail.next = curr; hundredTail = curr; }
                curr = prev.next;
            } else {
                prev = curr;
                curr = curr.next;
            }
        }

        prev.next = hundredHead;
        return dummy.next;
    }

    // Build linked list from array, apply rules, move 100s
    static Node maximizeScores(int[] arr) {
        if (arr.length == 0) return null;

        Node head = new Node(arr[0]);
        Node temp = head;
        for (int i = 1; i < arr.length; i++) {
            temp.next = new Node(arr[i]);
            temp = temp.next;
        }

        applyRule(head);
        return moveHundreds(head);
    }

    // Helper function to print linked list
    static void printList(Node head) {
        Node temp = head;
        while (temp != null) {
            System.out.print(temp.data);
            if (temp.next != null) System.out.print(" -> ");
            temp = temp.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {75, 59, 84, 84, 100, 90};
        Node head = maximizeScores(arr);
        printList(head);
    }
}
Python
# Node structure for Linked List
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

# Apply the rule: if X -> X -> 100 appears, update values
def applyRule(head):
    curr = head
    while curr and curr.next and curr.next.next:
        if curr.data == curr.next.data and curr.next.next.data == 100:
            
            # First X becomes 100
            curr.data = 100
            
            # Second X increases by 10% (floor)
            curr.next.data += curr.next.data // 10
        curr = curr.next

# Move all nodes with value 100 to the end
def moveHundreds(head):
    dummy = Node(-1)
    dummy.next = head
    prev = dummy
    curr = head
    hundredHead = hundredTail = None

    while curr:
        if curr.data == 100:
            prev.next = curr.next
            curr.next = None
            if not hundredHead:
                hundredHead = hundredTail = curr
            else:
                hundredTail.next = curr
                hundredTail = curr
            curr = prev.next
        else:
            prev = curr
            curr = curr.next

    prev.next = hundredHead
    return dummy.next

# Build linked list from array, apply rules, move 100s
def maximizeScores(arr):
    if not arr:
        return None

    head = Node(arr[0])
    temp = head
    for val in arr[1:]:
        temp.next = Node(val)
        temp = temp.next

    applyRule(head)
    return moveHundreds(head)

# Helper function to print linked list
def printList(head):
    temp = head
    while temp:
        print(temp.data, end="")
        if temp.next:
            print(" -> ", end="")
        temp = temp.next
    print()


if __name__ == "__main__":
    arr = [75, 59, 84, 84, 100, 90]
    head = maximizeScores(arr)
    printList(head)
C#
using System;
using System.Collections.Generic;

// Node structure for Linked List
class Node {
    public int data;
    public Node next;
    public Node(int x) { data = x; next = null; }
}

class GFG {

    // Apply the rule: if X -> X -> 100 appears, update values
    static void applyRule(Node head) {
        Node curr = head;
        while (curr != null && curr.next != null && curr.next.next != null) {
            if (curr.data == curr.next.data && curr.next.next.data == 100) {
                // First X becomes 100
                curr.data = 100;
                // Second X increases by 10% (floor)
                curr.next.data += curr.next.data / 10;
            }
            curr = curr.next;
        }
    }

    // Move all nodes with value 100 to the end
    static Node moveHundreds(Node head) {
        Node dummy = new Node(-1);
        dummy.next = head;
        Node prev = dummy, curr = head;
        Node hundredHead = null, hundredTail = null;

        while (curr != null) {
            if (curr.data == 100) {
                // Remove 100 node
                prev.next = curr.next;
                curr.next = null;

                // Append to 100s list
                if (hundredHead == null) hundredHead = hundredTail = curr;
                else { hundredTail.next = curr; hundredTail = curr; }

                curr = prev.next;
            } else {
                prev = curr;
                curr = curr.next;
            }
        }

        // Attach 100s at the end
        prev.next = hundredHead;
        return dummy.next;
    }

    // Build linked list from array, apply rules, move 100s
    static Node maximizeScores(int[] arr) {
        if (arr.Length == 0) return null;

        Node head = new Node(arr[0]);
        Node temp = head;
        for (int i = 1; i < arr.Length; i++) {
            temp.next = new Node(arr[i]);
            temp = temp.next;
        }

        // Apply X -> X -> 100 rule
        applyRule(head);

        // Move all 100s to the end
        return moveHundreds(head);
    }

    // Helper function to print linked list
    static void printList(Node head) {
        Node temp = head;
        while (temp != null) {
            Console.Write(temp.data);
            if (temp.next != null) Console.Write(" -> ");
            temp = temp.next;
        }
        Console.WriteLine();
    }

    static void Main() {
        int[] arr = {75, 59, 84, 84, 100, 90};
        Node head = maximizeScores(arr);
        printList(head);
    }
}
JavaScript
// Node structure for Linked List
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

// Apply the rule: if X -> X -> 100 appears, update values
function applyRule(head) {
    let curr = head;
    while (curr && curr.next && curr.next.next) {
        if (curr.data === curr.next.data && curr.next.next.data === 100) {
            // First X becomes 100
            curr.data = 100;
            // Second X increases by 10% (floor)
            curr.next.data += Math.floor(curr.next.data / 10);
        }
        curr = curr.next;
    }
}

// Move all nodes with value 100 to the end
function moveHundreds(head) {
    let dummy = new Node(-1);
    dummy.next = head;
    let prev = dummy;
    let curr = head;
    let hundredHead = null;
    let hundredTail = null;

    while (curr) {
        if (curr.data === 100) {
            // Remove 100 node
            prev.next = curr.next;
            curr.next = null;

            // Append to 100s list
            if (!hundredHead) hundredHead = hundredTail = curr;
            else { hundredTail.next = curr; hundredTail = curr; }

            curr = prev.next;
        } else {
            prev = curr;
            curr = curr.next;
        }
    }

    // Attach 100s at the end
    prev.next = hundredHead;
    return dummy.next;
}

// Build linked list from array, apply rules, move 100s
function maximizeScores(arr) {
    if (arr.length === 0) return null;

    let head = new Node(arr[0]);
    let temp = head;
    for (let i = 1; i < arr.length; i++) {
        temp.next = new Node(arr[i]);
        temp = temp.next;
    }

    // Apply X -> X -> 100 rule
    applyRule(head);

    // Move all 100s to the end
    return moveHundreds(head);
}

// Helper function to print linked list
function printList(head) {
    let temp = head;
    let res = [];
    while (temp) {
        res.push(temp.data);
        temp = temp.next;
    }
    console.log(res.join(" -> "));
}

// Example usage
let arr = [75, 59, 84, 84, 100, 90];
let head = maximizeScores(arr);
printList(head);

Output
75 -> 59 -> 92 -> 90 -> 100 -> 100



Article Tags :

Explore